PHP задачи с собеседований
3.05K subscribers
472 photos
6 videos
11 files
359 links
Задачи, тесты и теоретические вопросы по PHP.

Прислать задачу/вопрос в дар: @cyberJohnny
Сотрудничество: @cyberJohnny
Download Telegram
👨🏻‍💻 Оптимизация вставки или обновления множества значений в базу данных

Каждый раз после определенных манипуляций получается некий массив с уникальными словами:

$words = array(
"cat",
"dog",
"mouse",
"home",
...
);

Нужно каждое слово сохранить в таблице, если оно там не встречается и задать ему счетчик = 1.
Если слово встречается, то увеличить счетчик данного слова на 1.
С этим в принципе проблем нет, вопрос в другом. Иногда приходит массив на 1000 слов, и в целом может прийти и неограниченно больше. Сейчас проверка и запись в базу происходит тупо в цикле по одному.

Вопрос такой: можно ли как-то это оптимизировать, например, как-то обновлять таблицу одним запросом. Если да, то не будет ли какое ограничение по длине запроса. В целом, как бы вы сделали, посоветуйте варианты.

PHP задачи с собеседований
👨🏻‍💻 PhpStorm Live Templates for toArray() method

Мне нужно написать много Dto, а именно методы toArray() на PHP. Я искал в Интернете и допрашивал ChatGpt, но так и не смог получить четкий ответ.

Как мне написать шаблон, аналогичный __construct()? В его смысле. Я хочу создать метод в формате:

public function toArray(): array
{
return [
'id' => $this->getId(),
'name' => $this->getName(),
'alert' => $this->isAlert(),
'status' => $this->getStatus()
];
}

Но ничего не работает. Например, на вкладке “Settings > Editor > File and Code Templates > Code” я даже не могу добавить новый шаблон. Кнопка “Create Template” просто неактивна. Я не понимаю, как это работает, чтение документации JetBrains не помогло.

PHP задачи с собеседований
👎4
👨🏻‍💻 Вебхук Битрикс24 долго отвечает

Проблема: с сайта отправляется заявка в чат телеграм (через телеграм бот) и сразу в СРМ. Сервер ждёт ответа, телеграм отправляет заявку почти мгновенно, а от СРМ Битрикс24 бывает по 4 минуты нужно ждать ответа. И получается на сайте идёт загрузка несколько минут. Иногда Битрикс отвечает быстро, и загрузка только секунды 2, но не всегда.

Что с этим делать? Есть вариант ответить стороне клиента "OK", даже если СРМ ещё не ответила, надеясь, что лид успешно прийдёт. Но мне этот вариант не нравится, потому что есть вероятность что лид прийдёт только в телеграм, а в СРМ нет. И клиент будет потерян.

То есть проблема в скорости ответа СРМ.

Хостинг Fornex, локация Украина.

Ниже код, как я отправляю данные (типа REST API если я правильно понял). Метод вебхука crm.lead.add

// отправляем запрос в Б24 и обрабатываем ответ
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_SSL_VERIFYPEER => 0,
CURLOPT_POST => 1,
CURLOPT_HEADER => 0,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $queryURL,
CURLOPT_POSTFIELDS => $queryData,
));
$result = curl_exec($curl);
curl_close($curl);
$result = json_decode($result,1);

// если произошла какая-то ошибка - выведем её
if(array_key_exists('error', $result)){

die("Ошибка при сохранении лида: ".$result['error_description']);
//echo 'false';

}else{

echo 'true';

}

PHP задачи с собеседований
👎11
👨🏻‍💻Вопрос от пользователя

Не могу поднять локально страницу на Laravel

При запуске страницы вижу ошибку (на картинке)

Я сам фронт, вообще не понимаю как это решить Как это исправить? Запускаю через live server.

PHP задачи с собеседований
👎2👍1
👨🏻‍💻Вопрос от пользователя

Liqpay не отправляет callback после успешной оплаты

Подключаю платёжную систему liqpay к сайту, используя их платёжную страницу (checout), перенаправляю на неё пользователя с данными об оплате. Но после совершения оплаты мне нужно как-то получить callback от сервера liqpay что-бы я понимал что пользователь совершил оплату. На сколько я понял из их документации для этого в массив с данными об оплате нужно добавить server_url в котором укажу куда liqpay должен отправить запрос с данными об оплате после оплаты, но этого не происходит совсем.

Он отправит эти данные только если я добавлю в массив result_url с url ссылки куда пользователь сможет перейти после оплаты что-бы вернуться обратно на сайт, и если он таки перейдёт по этой ссылке то туда вместе с переходом liqpay таки отправит запрос с данными, но пользователю ведь совсем не обязательно переходить на сайт по этой ссылке, а если он этого не сделает то я не получу информацию что он совершил оплату а значит не смогу увеличить ему баланс.

Может кто-то уже работал с liqpay и знает в чём дело? Почему он не отправляет callback после успешной оплаты?
PHP задачи с собеседований
👨🏻‍💻 Многопоточный обход массива\строки средствами php

Допустим есть строка, которая состоит из символов в кол-ве от 400 до 800 тысяч штук и длина которой кратна четному числу. Мы ее превращаем в массив:

$string = str_split('1234567890.......');

и делим на, допустим, 8 кусков, создавая массив из 8 строк;

$combine = array_chunk($string,8);

После чего с каждой переменной данного массива, посимвольно, работает некоторая функция и потом результат работы собирается обратно в обновленную строку $string.

Вопрос - есть ли корректный способ сделать так, чтобы каждый экземпляр массива $combine обрабатывался функцией параллельно, а не ждал пока будет его очередь при линейном обходе средствами foreach?

У меня сервер на windows, с апачем и php 7.4\8.2, php подгружается как модуль для Apache. Читал что при подобном варианте возможно только использовать proc_open для многопоточного серверного вычисления, но не совсем понимаю как это можно реализовать. Может есть какие-то рабочие примеры? Не очень хочется городить кривой велосипед из multicurl с обращениями самой страницы к себе и выдергиваниями фрагментов кода, т.к. это явно все будет работать через 3 палки и криво. Нужно что-то кроме shell_exec, т.к. при работе с ним возможны ошибки, если страница закрывается раньше чем завершается работа консольного cli интерфейса.

На данный момент обход всей строки обычным способом занимает около 37 секунд, что крайне много и есть сильное желание сократить как-то это значение.

UPD

Основное время затрачивается именно на линейный обход строки в массиве и преобразование данных в ней же. Поэтому рассматривается вариант параллельной обработки нескольких переменных массива одновременно.

PHP задачи с собеседований
👨🏻‍💻 Не идет запись в базу данных

Такое ощущение, будто массивы не идут. Цикл не запускается, я добавляю как положено, Excel файл, но загрузка останавливается. Что нужно сделать?

<?php
include 'include/db.php';
include 'assets/vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\IOFactory;
error_reporting(E_ALL);
ini_set('display_errors', 1);


if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_FILES['add_file']) && $_FILES['add_file']['error'] === UPLOAD_ERR_OK) {
$file_path = $_FILES['add_file']['tmp_name'];

$spreadsheet = IOFactory::load($file_path);
$worksheet = $spreadsheet->getActiveSheet();
echo 'Обработка файла</br>';
$keywords = array(
"source_operator" => array("source", "operator"),
"start_time_stamp" => array("start", "time", "stamp"),
"subscriber_relation" => array("subscriber", "relation"),
"msisdn" => array("msisdn", "ISND"),
"other_party" => array("other", "party"),
"redirecting_number" => array("redirecting", "number"),
"call_duration" => array("call", "duration"),
"call_status" => array("call", "status"),
"cause" => array("cause"),
"imsi" => array("imsi"),
"imei" => array("imei"),
"imsi_called" => array("imsi", "called", "party"),
"imei_called" => array("imei", "called", "party"),
"lac" => array("LAC"),
"cell_id" => array("cell", "ID"),
"base_station_location_address" => array("base", "station", "location"),
"azimuth" => array("azimuth"),
"lon" => array("lon"),
"lat" => array("lat"),
"radius" => array("radius"),
"region" => array("region"),
"record_type" => array("record", "type"),
"record_id" => array("record", "ID", "номер"),
"calling_party_number" => array("calling", "party", "number"),
"called_party_number" => array("called", "party", "number"),
"supplementary_services" => array("supplementary", "services"),
"msisdn_calling_party" => array("msisdn", "calling", "party"),
"msisdn_called_party" => array("msisdn", "called", "party"),
"calling_party_category" => array("calling", "party", "category"),
"operator_id" => array("operator", "Identification"),
"connected_number" => array("connected", "number"),
"msc_number" => array("MSC", "number"),
"date_and_time" => array("Date", "time"),
"call_direction" => array("call", "direction"),
"vlr_number" => array("vlr", "number"),
"roaming_number" => array("roaming", "number"),
"forwarding_reason" => array("forwarding", "reason"),
"ss_code" => array("ss-code"),
"ussd" => array("ussd"),
"access_delivery" => array("access", "delivery"),
"redirection_number" => array("redirection", "number"),
"redirection_information" => array("redirection", "information"),
"call_id_number" => array("call", "Identification", "Number"),
"data_validity" => array("Data", "Validity"),
"network_provider_id" => array("network", "provider", "ID"),
"progress" => array("progress"),
"dpc" => array("dpc"),
"opc" => array("opc"),
"location_number" => array("location", "number"),
"account_code_imput" => array("account", "code", "input"),
"tmsi_calling_party" => array("TMSI", "calling", "party"),
"tmsi_called_party" => array("TMSI", "called", "party"),
"hlr_number" => array("HLR", "number"),
"location_info_calling_party" => array("location", "calling", "party"),
"location_info_called_party" => array("location", "called", "party"),
"ciphering_mode" => array("ciphering", "mode"),
"answer_time" => array("answer", "time"),

"realease_time" => array("realease", "time"),
"seizure_time" => array("seizure", "time"),
"event_type" => array("Event", "type"),
"base_station_type" => array("base", "station", "type"),
);




$firstRow = $worksheet->getRowIterator()->current();
$cellIterator = $firstRow->getCellIterator();

$column_index = array();
foreach ($cellIterator as $cell) {
$cellValue = $cell->getValue();

foreach ($keywords as $keyword => $columnKeywords) {
if (in_array(strtolower($cellValue), array_map('strtolower', $columnKeywords))) {
$column_index[$keyword] = $cell->getColumn();
}
}
}


$data_to_insert = array();

foreach ($column_index as $keyword => $columnLetter) {
$column_data = array();

foreach ($worksheet->getColumnIterator($columnLetter) as $column) {
foreach ($column->getCellIterator() as $cell) {
$cellValue = $cell->getValue();
$column_data[] = $cellValue;
}
}

$data_to_insert[$keyword] = $column_data;
}



echo 'Добавление в базу данных.</br>';
$total_rows = count($data_to_insert);
$current_row = 0;


// Подготовка SQL-запроса для вставки одной строки
$insertQuery = "INSERT INTO mobiles2 (
source_operator, start_time_stamp, subscriber_relation, msisdn, other_party, redirecting_number,
call_duration, call_status, cause, imsi, imei, imsi_called, imei_called, lac, cell_id,
base_station_location_address, azimuth, lon, lat, radius, region, record_type, record_id,
calling_party_number, called_party_number, supplementary_services, msisdn_calling_party,
msisdn_called_party, calling_party_category, operator_id, connected_number, msc_number,
date_and_time, call_direction, vlr_number, roaming_number, forwarding_reason, `ss-code`,
ussd, access_delivery, redirection_number, redirection_information, call_id_number, data_validity,
network_provider_id, progress, dpc, opc, location_number, `account_code_input`, tmsi_calling_party,
tmsi_called_party, hlr_number, location_info_calling_party, location_info_called_party,
ciphering_mode, answer_time, realease_time, seizure_time, event_type, base_station_type
) VALUES (
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
)";

$stmt = $db->prepare($insertQuery);
if (!$stmt) {
echo "Ошибка при подготовке SQL-запроса: " . $db->error;
exit;
}

foreach ($data_to_insert as $rowIndex => $sourceOperator) {
// Создаем массив с данными для вставки в базу данных для текущей строки
$rowData = array();
foreach ($column_index as $keyword => $columnLetter) {
$rowData[] = $data_to_insert[$keyword][$rowIndex];
}

// Привязываем параметры и выполняем запрос для текущей строки
$bindParams = str_repeat('s', 61); // Поскольку у вас 61 столбец
$stmt->bind_param($bindParams, ...$rowData);

$result = $stmt->execute();
if (!$result) {
echo "Ошибка при выполнении запроса для строки $rowIndex: " . $stmt->error;
} else {
echo "Данные для строки $rowIndex успешно обработаны и добавлены в базу данных.</br>";
}
}


$stmt->close();



} else {
echo "Ошибка при загрузке файла." . $_FILES['add_file']['error'];
exit;
}
} else {
echo "Недопустимый метод запроса.";
exit;
}
?>

PHP задачи с собеседований
👎28
👨🏻‍💻 Удалить повторения подстроки в строке

Есть строка условно говоря такого вида:

petya kolya vasya oleg misha vasya vasya ivan vasya

Как на php удалить из неё все повторяющиеся подстроки vasya, кроме первой, чтобы осталось

petya kolya vasya oleg misha

PHP задачи с собеседований
👍1
👨🏻‍💻 Найти корректно число старта xref таблицы в pdf документе

Допустим у меня есть большой pdf файл версии 1.6. И в конце файла должна быть информация:

startxref
5638681
%%EOF

Благодаря которой, естественно, система знает положение начала xref таблицы пдфа. Но у меня там значится только:

startxref
56386

И естественно файл сыпется и везде не читается. Этот файл лишь как пример. Основной вопрос заключается в том - возможно ли как-то на лету пересчитать положение начала xref и проставить его(число) в нужном месте в конце файла, чтобы даже в случае ошибки она была исправлена и файл бы прочитался? Я поискал по документу и слово Xref, кроме конца в startxref, встречается только в самом конце документа, аж на 28164 строке, в потоке прямо перед концом файла и словом startxref. Получается как-то вот так:

<</DecodeParms<</Columns 5/Predictor 12>>/Filter/FlateDecode/ID[]/Info 81 0 R/Length 467/Root 83 0 R/Size 155/Type/XRef/W[1 3 1] вот в этом фрагменте:

154 0 obj
<</DecodeParms<</Columns 5/Predictor 12>>/Filter/FlateDecode/ID[<A95E63F8E64607C01DE088DCA9B76927><A934A84176582B4C8931FAEC898E990B>]/Info 81 0 R/Length 467/Root 83 0 R/Size 155/Type/XRef/W[1 3 1]>>stream
hЮ¬’1LSQ†П=ЇTh…гD\”(С :tPг`Xl|qa`qRЌ@HCЦД'BЊ,jBd!Д°‡VЁ‰ў‰>ќФШ(¶Шw|зЬЮј6ДЌелџпю9чјж" 8ЂРHptьП9яє"~F!…їnђыкс‚ц€d§Z<ц/|_њzЅ…tдД·љсї]WыТ±іy>ыпгЭЪ· uЅ-пѕ{бЅцa¤УwЖЄ¦яссeн!х\Я¬˜~юйOн[‘вгkЊПҐKЪ·!ќ+>Ъ5s2v\ыТEы|ЩфЯТЪG‘О¬пяjіюЅ‡‘’эЈЫfОвrBыv¤«gпmїђн“я •уБтНЛXНMя'-Y=Ђ[
у§uV•ЗќјХзouТjЮJ9_њ#“|ЪЩіoзыН3эi)Џэн-4E ~-аEдЮ’0,¦-0d3±Tп“уcKЮШ„LdZ]LUх©zу’‡˜xSr«4o3/eЕИ¶±њд‡Т\’Ь!Н»МДІ˜1IЙЙ z&чкУS|otКзьЮњ˜OТМЯ WВКьЄдХ†УS?u…Эrы°d~3Ч*рOЂ ш…§±
endstream
endobj
startxref
56386

Я уже пыталя по советам с интернета подсчитать в байтах кол-во символов перед словом xref с начала файла, но там переваливает значение за 9 лямов, а мне надо ровно 5638681. Сам вес файла кстати 5 639 408 в байтах. Есть ли какие-то рабочие способы такого подсчета или может какие-то консольные утилиты, которым можно скормить файл и в ответ получить нужное значение старта xref?

PHP задачи с собеседований
👎6👍1🔥1
👨🏻‍💻Вопрос от пользователя

Как установить Thumbnail Категории через код?

Господа, не пойму как установить картинку для категории в WP? В теме они поддерживаются, вручную установить можно. set_post_thumbnail - не отрабатывает. У меня есть код:

foreach ($house['renderer'] as $foto) {
$img_id[]['picture'] = media_sideload_image($foto, 'product_cat_' . $insert_res['term_id'], '', 'id');
}
update_field('foto', $img_id, 'product_cat_' . $insert_res['term_id']);
set_post_thumbnail('product_cat_' . $insert_res['term_id'], $img_id[0]['picture']);

Загружаю фото со стороннего ресурса, получаю id фото в массив, передаю в update_field - отрабатывает отлично, фотки подключаются в множственное поле ACF с изображениями. $img_id[0]['picture'] - ID вложения, всё верно. Но не работает((

PHP задачи с собеседований
👨🏻‍💻Вопрос от пользователя

Объединение массива

Существует вывод данных из базы, необходимо объединить все данные из массивов и вывести полученный массив только с уникальными значениями

Array ( [0] => 83 ) Array ( [0] => 85 )
Array ( [0] => 77 ) Array ( [0] => 85 )
Array ( [0] => 83 ) Array ( [0] => 85 )Array ( [0] => 55 ) Array ( [0] => 99 )

выглядит вот так введите сюда описание изображения

    $sql222 ="select DISTINCT number_cont from  ".$new_array[$i]."";
$result222 = mysqli_query($con, $sql222);
if(mysqli_num_rows($result222) > 0)
{
echo '<table>';
while($row = mysqli_fetch_assoc($result222))
{
$re=array_merge((array)$row["number_cont"]);
print_r($re);
}
echo '</table>';
}


В PHP вообще не силен, поэтому прошу помощи

PHP задачи с собеседований
Почему возникает ошибка при попытке передать данные в виде JSON из PHP в JS?

Данные на странице выводятся нормально. Но когда пытаюсь их передать js обработчику для корзины, выдает ошибку. Вот код шаблона:

foreach ($dishes as $item) {
<div class="products_one_price_card">
<?php
$productJSON = json_encode($item, JSON_UNESCAPED_UNICODE);
?>
<button data-product="<?php echo $productJSON; ?>">В КОРЗИНУ</button>
</div>
}


код js:

const oneProductCardButton = document.querySelectorAll('.products_one_price_card button');

oneProductCardButton.forEach((oneProductCardButtonItem) => {
oneProductCardButtonItem.addEventListener('click', (event) => {
const productJSON = oneProductCardButtonItem.getAttribute('data-product');
const product = JSON.parse(productJSON);

console.log(product);
});
});


и выдает ошибку: Uncaught SyntaxError: Expected property name or '}' in JSON at position 1 (line 1 column 2) at JSON.parse () at HTMLButtonElement.

Я вывожу переменную $productJSON с помощью var_dump, вроде выводится нормальный json:

{"id":"1","name":"Пицца 4 сезона","eng_name":"pizza-4-sezona","description":"Здесь краткое описание если нужно, состав, ингридиенты и т.д.","img":"pizza-4-sezona-family-time.jpg","price":"3200","category":"pizza","dishes_option_name":"pizza_size","dishes_option_values":"30_3200,40_3900"}


в чем может быть проблема?

PHP задачи с собеседований
👨🏻‍💻Вопрос от пользователя

Telegram API: кнопка с заготовленным сообщением для бота


Имеется канал в telegram, в него добавлен бот со всеми правами администратора. Можно ли сделать так, что при клике на кнопку будет открываться диалог с ботом с заготовленным сообщением. Как будто пользователь уже нажал кнопку start, плюс бот получил какую-то служебную информацию, а нажатой кнопке? Грубо говоря, нужно добавить в кнопу url (на бота), callback_data и начать при этом диалог с ботом. Такое реально? Библиотеки не использую, пишу на чистом php. Заранее всем спасибо.

PHP задачи с собеседований
Почему на PHP код не работает как на Javascript?

Есть Javacript и работает идеально:

if (!navigator.cookieEnabled !window.caches) {
document.cookie = "referrer=" + document.referrer;
window.history.back();
}


Но на PHP возвращает на домен (например возвращает yandex ru, а заходил с yandex ru/kupti-slona), а мне надо на предыдущую страницу.

if (!isset($_COOKIE['referrer']) && (!isset($_SERVER['HTTP_CACHE_CONTROL']) $_SERVER['HTTP_CACHE_CONTROL'] !== 'max-age=0')) {
setcookie('referrer', $_SERVER['HTTP_REFERER'], time() + 3600, '/');
header('Location: ' . $_SERVER['HTTP_REFERER']);
exit;
}


PHP задачи с собеседований
👎2