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

Прислать задачу/вопрос в дар: @cyberJohnny
Сотрудничество: @cyberJohnny
Download Telegram
Bitrix и его файл init.php

сем привет! Подскажите пожалуйста проблема заключается в том что на локальном проекте под битрикс в папке php_interface создал файл init.php и просто хочу вывести текст - только вот выводит текст или что либо в самом конце сайта. Знаю то что все содержимое файла init должно подгружаться в начале сайта. Кто ни будь сталкивался с такой проблемой?
Как отображать имена внутри события fullcalendar?

Видел на других сайтах возможность в fullcalendar отображать имена пользователей, к примеру кто забронировал комнату. (прикрепил скрин) Подскажите пожалуйста как это реализовать?
Взаимодействие из JS с функцией в PHP через JSON запрос

Задача. Нужно без обновления страницы вывести данные из базы данных в модальное окно, которое открывается при нажатии на кнопку. Для этого в JS я вызываю функцию PHP и передаю несколько параметров через JSON, затем также через JSON возвращаю массив с данными из таблицы базы данных.

let params = {
userfunc: 'get_preview',
modul: 'home',
id: 1
};
let response = await fetch('./functions/functions.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify(params),
});
if (response.ok) {
let result = await response.json();
console.log(result);
};
в PHP пишу следующий код

function get_preview($module, $id) {
global $db;
$result = $db -> prepare("SELECT * FROM $module WHERE status != '0'");
$result->execute(array($id));
$result = $result->fetch(PDO::FETCH_LAZY);
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK);
}
header('Content-Type: application/json');
$param = json_decode($_POST['params']);
$userfunc = $param['userfunc'];
$module = $param['modul'];
$id = $param['id'];
if ($userfunc == 'get_preview') {
get_preview($module, $id);
}
Постоянно появляется ошибка JSON, помогите пожалуйста сделать код рабочим.
Проверка на наличие существующего элемента в инфоблоке по свойству (Битрикс)

Друзья заранее прошу, отнестись к вопросу не очень строго, пишу скрипт первый раз.

Есть 2 инфоблока:

Инфоблок (ID=2) с товарами, там собираю массив с артикулами на WB;
Инфоблок (ID=7) туда добавляю сами отзывы (которые забираю по API).
Функция скрипта: По API получаю отзывы с WB по определенным товарам (по артикулу WB, которые указаны в инфоблоке с товарами) и добавляет элементы в инфоблок с отзывами.

Подскажите пожалуйста как сделать, чтобы при выполнении функции проверялось, на наличие этого отзыва (то есть при повторном запуске скрипта, те что уже есть не добавлялись), у каждого отзыва с WB есть уникальный ID (пример: kzgXM4MB65w5GC7j5vjK), вот по этому свойству элемента инфоблока с отзывами (ID 7) и проверять на существования отзыва.

Заранее всем благодарен за помощь!

<?php
// подключение функций пролога
require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/prolog_before.php");

set_time_limit(60);

CModule::IncludeModule("main"); // CFile
CModule::IncludeModule("iblock"); // CIBlockElement

$PRODUCT_IBLOCK = '2';
$REVIEWS_IBLOCK = '7';

function getRequestResult($request)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $request);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$headers = array();
$headers[] = 'Content-Type: application/json';
$headers[] = 'Authorization: ........';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
return $result;
}

function parseAndAdd($artnum, $PRODUCT_IBLOCK) {
$org_url = 'https://feedbacks-api.wildberries.ru/api/v1/feedbacks?isAnswered=true&nmId='. $artnum .'&take=5000&skip=0';
$html = getRequestResult($org_url);

$arr = json_decode($html, true);
$counter = 0;

foreach($arr['data']['feedbacks'] as $value){

//Свойства
$PROP = array();
$i = 0;
if (!empty($value['photoLinks'])) {
foreach ($value['photoLinks'] as $morePhoto) {
$arMorePhoto['n'.$i] = array("VALUE"=>CFile::MakeFileArray($morePhoto['fullSize']));
$i++;
}
}
$PROP['ART_WB'] = $value['productDetails']['nmId'];
$PROP['RAITING'] = $value['productValuation'];
$PROP['ISTOCHNIK'] = $value['state'];
$PROP['PHOTO'] = $arMorePhoto;
$PROP['REVIEWSID'] = $value['id'];

//$photolinks[] = $value['photoLinks'];
/*if (!empty($photolinks)) {
foreach($photolinks as $photo){
$photo = $photo['fullSize'];
}
}*/

$el = new CIBlockElement;
$fields = [
'ACTIVE' => "Y",
'IBLOCK_ID' => 7,
"IBLOCK_SECTION_ID" => false,
"NAME" => $value['userName'],
"PREVIEW_TEXT" => $value['text'],
"PREVIEW_PICTURE" => $imgUrl ? CFile::MakeFileArray($imgUrl) : CFile::MakeFileArray($_SERVER["DOCUMENT_ROOT"]."/local/api/wb/avatar.png"),
"PROPERTY_VALUES" => $PROP,
//'ACTIVE_FROM' => $date, // Начало активности
//'DATE_CREATE' => $date, // Дата создания
];

if ($PRODUCT_ID = $el->Add($fields)) {
echo 'Добавлен отзыв, ID: ' . $PRODUCT_ID . '<br />';
$counter++;
} else {
echo "Error[" . $PRODUCT_ID . "]: " . $el->LAST_ERROR . '<br />';
}

}

echo 'Отзывы по товару с артикулом '.$artnum . ' добавлены. Количество '. $counter. '<br>';

}

//print_r($photo);
//print_r(parseAndAdd(113509876, 6));
$places_ids = []; // Храню артикулы всех товаров, по которым будет забирать отзывы
$arSelect = ["NAME","PROPERTY_ART_WB"];
$arFilter = ["IBLOCK_ID" => $PRODUCT_IBLOCK,"ACTIVE" => "Y",];
$resp = CIBlockElement::GetList(Array(), $arFilter, false, false, $arSelect);
while($ob = $resp->GetNextElement()) {
$arFields = $ob->GetFields(); // Получаю значения полей элемента
$places_ids[] = $arFields['PROPERTY_ART_WB_VALUE']; // Заполняю массив с артикулами
}

foreach ($places_ids as $arrwb) {
if (!empty($arrwb)) {
parseAndAdd($arrwb, 7);
}
}
?>
Подключение скриптов и стилей на уровень выше корневой директории

Пытаюсь реализовать собственную cms для своего сайта в качестве практики php, но столкнулся со следующей проблемой (Картинка)
Имеется иерархия проекта описанная выше. В папке core основные важные скрипты, по типу базового контроллера, подключения к БД и др, В папке develop находятся пользовательские контроллеры, представления, модели и шаблоны В папке public только .htaccess, index.php который вызывает bootstrap.php из core и иконка сайта

При нужном url я вызываю требуемый контроллер и подключаю:

шапку сайта
представление
подвал сайта
но мне очень нравится идея с шаблонами, и понравилась bitrix структура шаблонов, поэтому я хотел бы сделать это и у себя. Шаблоны, как я и писал выше, хранятся в /develop/templates. Корневая директория сайта /public/

Пробовал относительные пути по совету ChatGPT и людей с форумов, не помогает

(../../develop/...)
Пробовал реализовать перенаправление в htaccess

RewriteCond %{REQUEST_URI} ^/templates/admin/(.*)$
RewriteCond %{REQUEST_URI} !/develop/templates/(.*)$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/../templates/$1 [L,R=301]
но пока что ничего не помогает, а хранить шаблоны в public мне не очень нравится...

Собственно, вопрос: Можно ли реализовать подключение стилей, скриптов, картинок через php и htaccess, не затрагивая конфиг файл httpd? Пока что видел только такое решение, но хотел бы его избежать, чтобы сайт был легк переносим.

P.S. Забыл написать, что также нашел решение

echo '<style>';
include <путь к стилю>
echo '</style>';
Насколько такое решение будет... Неправильным, при создании шаблонов?
Ошибка Call to undefined function mysqli_connect()

Не могу подключить базу данных к сайту. При попытке подключить БД выдаётся такая ошибка:

Fatal error: Uncaught Error: Call to undefined function mysqli_connect() in D:\Проекты\Новая папка\index.php:11 Stack trace: #0 {main} thrown in D:\Проекты\Новая папка\index.php on line 11

У меня OC Windows 11

Вот мой код:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<p>Не работает php</p>
<?php
$connection=mysqli_connect('localhost', 'root', '', 'data');
$sql = "SELECT Name FROM tablical";
$massive=mysqli_query($connection, $sql);
$data=mysqli_fetch_assoc($massive);
foreach ($data as $key => $value) {
print_r($value);
}
?>



</body>
</html>
Авторизация действий над определенными полями на основе ролей и разрешений

Использую пакет spatie-permission, Laravel 11.У юзера есть permission формата entity.action.value, например - order.edit.description(редактировать описание заказа) или order.see.Accepted (видеть заказы со статусом Accepted). У меня появились две идеи как это авторизовать: первая - написать кастомное правило валидации и применить к каждому полю в FormRequset:

public function validate(string $attribute, mixed $value, Closure $fail): void
{
if (!Gate::allows($this->action,[$attribute,auth()->user()])){
$fail('You do not have permission to interact with this field.');
}
}
Gate:

Gate::define('order-edit-field', function (User $user,string $attribute): bool {
return (in_array($attribute,$user->convertPermissionToValue('order.edit')) || $user->isAdmin());
});
Идея в чем - все разрешения обрезаются с помощью convertPermissionToValue() до value , и это value сравнивается с пришедшем с реквеста полем.

Вторая мысль - через политики:

public function update(User $user, Order $order,array $data): bool
{
if ($user->isAdmin()){
return true;
}

$fields = $user->convertPermissionToValue('order.edit');
$statuses = $user->convertPermissionToValue('order.view');
return in_array($order->status,$statuses)
&& array_reduce(array_keys($data),function ($accum, $item ) use ($fields){
return in_array($item,$fields) && $accum;
},true);
}
Сравнивается .value и fields реквеста, если какого то field нет в value - 403. Таким же образом проверяются любые действия над сущностями - permissions обрезаются до value, value сравнивается с полями ,со статусами, и вообще с чем угодно ,над чем нужно будет совершить action.

В чем собственно говоря вопрос: хоть один из этих вариантов - так вообще норм делать ? Сколько бы не гуглил, я не смог найти как именно организовать авторизацию действий над конкретными полями. Есть какие примеры реализации такого, как бы это вы сделали, где разумно было бы делать подобные проверки, хорошая ли вообще идея с convert разрешений, рабочая ли идея с такими составными permission. Буду ооочень благодарен за любую помощь или подсказку, ибо я новичок и даже те два примера выше выдались огромными нервозатратами)
Качество кода, архитектуры. Service and Repository pattern. PHP & Laravel

Стремлюсь к очень качественному коду, посоветоваться не с кем. Вычитал очень много про архитектуру и пришел к этому (Пример на PHP Laravel)

Middleware - Прослойка запроса, проверка аутентификации и подобного, если это необходимо

FormRequest - Тут мы делаем валидацию запроса(Если это не GET)

Controller - тут мы принимаем запрос, делаем валидацию, если FormRequest не предусмотрен, отдаем это всё в Service и затем отдаём ответ

Service - Тут вся бизнес логика, обращение к Repository

ServiceInterface - интерфейс для нашего Service, для гибкости кода

Repository - логика обращения к базе данных, модели, все запросы и т д

RepositoryInterface - интерфейс для Repository, так же для гибкости

Затем мы регистрируем наши интерфейсы и их реализацию в ServiceProvider и работаем по такой архитектуре.

Хотел спросить - всё ли верно, не излишне ли, стоит ли добавить какой то шаг или же убрать. Спасибо
Как устроена реализация в играх кликерах обработка и сохранение кликов в бд?

Каждый клик допустим это +N монет. Отправлять при каждом клике на фронте событие в виде простого запроса на бэк, где инкрементируется значение в бд - очевидное и простое решение, но будет высокая нагрузка на бэк. Поэтому интересно как лучше всего решать задачи подобного плана и какие инструменты использовать.

Я так понимаю для таких задач нужен какой то демон на сервере собирающий события пользователей о кликах в оперативке и после интервально сохранять в БД подсчитав и проверив данные, так как хранить на фронте даже шифруя наверное будет опрометчиво и при желании можно будет обмануть сервер? Какими инструментами лучше решать эту задачу? nginx push stream, socketio nodejs или есть еще варианты?

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

Всем привет.

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

Источник->Раздающий скрипт->Потребители

То есть, я получаю по вебсокету и по curl определенные данны. По вебсокету бегут постоянно, по curl более статичные. Мне нужно, желающим, эти данные отдавать не неся нагрузку на Источник. То есть Источник только предоставляе их одному сайту, а тот сайт уже раздает другим.

Вопрос в том, как правильно организовать раздачу вебсокета, если к Источнику я могу подключить только один канал?

Я с вебсокетом работал только в простом варианте - получить, отправить и т.д.
laravel pusher не работает почему то отправка

'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'host' => env('PUSHER_HOST') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com',
'port' => env('PUSHER_PORT', 443),
'scheme' => env('PUSHER_SCHEME', 'https'),
'encrypted' => true,
'useTLS' => env('PUSHER_SCHEME', 'https') === 'https',
],
'client_options' => [
// Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html
],
],
Файл конфигурации не трогал просто добавлял в env креды ,на прямую креды работают если использовать

public function sendTestMessage()
{
$options = [
'cluster' => env('PUSHER_APP_CLUSTER'),
'useTLS' => true
];
$pusher = new Pusher(
env('PUSHER_APP_KEY'),
env('PUSHER_APP_SECRET'),
env('PUSHER_APP_ID'),
$options
);

$data['message'] = 'hello world';
$pusher->trigger('test-channel', 'my-event', $data);

return response()->json(['message' => 'Event has been sent!']);
}
Отправляю Event после того как создал заказ но сам event не приходит в pusher Debug Console

Использую laravel 11
Разделить список директории на дочерние и родительские

Подскажите правильное направление или пример. Есть список:

$list = ['folder', 'folder2','folder2/items','folder2/items/css','folder2/images'];
Нужно получить многомерный массив с дочерними элементами:

$list = [
["name" => "folder", "path" => "/folder", children: []],
["name" => "folder2", "path" => "/folder2", children:
[
"name" => "items", "path" => "/folder2/items", children:
[
"name" => "css", "path" => "folder2/items/css", children: []
],
"name" => "images", "path" => "/folder2/images", children: [],
]
],
];
Bitrix24 вызов попапа посредством события в inti.php

В init.php прописываю событие, которое должно открывать попап после сообщения в открытых линиях, само событие отрабатывает, в лог пишет. Но попап в CRM не открывается. Вот само событие:

AddEventHandler("imopenlines", "OnSessionStart", "OnFirstMessage");
function OnFirstMessage($arFields) {
$chatId = $arFields['CHAT_ID']; // Логируем ID чата в файл для дальнейшей обработки
file_put_contents(__DIR__."/test.txt", $chatId . PHP_EOL, FILE_APPEND);
\Bitrix\Main\Page\Asset::getInstance()->addString('
<div id="openline_confirm"></div>');
\Bitrix\Main\Page\Asset::getInstance()->addString('
<script>
BX.ready(function() {
var Confirmer = new BX.PopupWindow("openline_confirm", null, {
content: "<div></div>" + "<h3>Новое сообщение в открытых линиях</h3>",
closeIcon: {
right: "20px",
top: "20px"
},
width: 350, // ширина окна
height: 150, // высота окна
zIndex: 100, // z-index
draggable: false, // можно двигать или нет
resizable: true, // можно ресайзить
min_height: 250, // минимальная высота окна
min_width: 100, // минимальная ширина окна
overlay: {
backgroundColor: "black",
opacity: "80"
},
buttons: [
new BX.PopupWindowButton({
text: "Принять",
className: "popup-window-button-accept",
events: {
click: function() {
BX.Messenger.Public.openLines();
this.popupWindow.close();
}
}
}),
new BX.PopupWindowButton({
text: "Отклонить",
className: "webform-button-link-cancel",
events: {
click: function() {
this.popupWindow.close();
}
}
})
]
});
Confirmer.show();
});
</script>');
CJSCore::Init(array("Confirmer"));
}
При событии js на стороне клиента не добавляется, как это можно реализовать?
Ошибка в получении данных VK Api

Подскажите почему возникает ошибка "Ошибка при получении данных"? Ничего не отдается хотя id и токен ввожу правильно

<?php
$group_id = '******';
$access_token = '********';
$count = 5; // Количество постов

$url = "https://api.vk.com/method/wall.get?owner_id=-$group_id&count=$count&access_token=$access_token&v=5.131";
$response = file_get_contents($url);
$data = json_decode($response, true);

if (isset($data['response']) && isset($data['response']['items'])) {
$posts = $data['response']['items'];

foreach ($posts as $post) {
// Выводим текст поста
echo $post['text'] . '
';

// Дополнительные действия с постом
// Например, вывод изображений, комментариев и т.д.
}
} else {
echo 'Ошибка при получении данных';
}
?>
php
Как установить правильно sqlsrv для php?

0

В общем я пытался установить sqlsrv, с помощью вот этой документации: https://learn.microsoft.com/ru-ru/sql/connect/php/microsoft-php-driver-for-sql-server?view=sql-server-ver16#getting-started, но у меня после вызова phpinfo нет sqlsrv. Что находиться в php(Тип файла INI-DEVELOPMENT):

extension_dir = "C:\php\ext"
extension=php_pdo_sqlsrv_82_ts_x64.dll
extension=php_sqlsrv_82_ts_x64.dll
Моя версия php: PHP Version 8.2.20 Мне это нужно для того, чтобы подключиться ко внешней БД, со своего локального ПК (у меня нет сервера). Но у меня появилась ошибка: Fatal error: Uncaught Error: Call to undefined function sqlsrv_connect() in C:\Users\ivakov.av\Desktop\Php_Projects\sigur.php:15 И мне надо установить корректно sqlsrv, помогите, пожалуйста!

// Подключаемся к MS SQL
$serverName = ""; // Имя сервера MS SQL
$connectionInfo = array(
"Database" => "", // Имя базы данных
"UID" => "", // Имя пользователя
"PWD" => "" // Пароль
);
$conn = sqlsrv_connect($serverName, $connectionInfo);

if ($conn === false) {
echo "Connection failed: " . print_r(sqlsrv_errors(), true);
exit;
}
PHP parse/syntax errors; Ошибки Unexpected XXX и как решить их

Часто программисты допускают ошибки. Могут возникать ошибки синтаксиса. Например:

PHP Parse error: syntax error, unexpected '{' in index.php on line 20

Неожиданный символ не всегда является настоящим виновником. Но номер строки дает приблизительное представление о том, с чего начать поиск.

Всегда смотрите на контекст кода. Синтаксическая ошибка часто кроется в упомянутых или в предыдущих строках кода. Сравните свой код с примерами синтаксиса из руководства.
cms для блога прошу о помощи

здравствуйте у меня такой вопрос я пока нечего не понимаю в программирования решил разработать cms для блога , в краце подскажите пж как создать связь меж этими таблицами я пользуюсь PhpMyAdmin id | login | password | screen_name

#posts id | alias | author_id | date_posted

#posts_content post_id | language_id | title | post_body

#comments id | post_id | author_id | text | date_posted | parent_comment_id
Каким образом можно автоматизировать HTTP запросы на интернет-ресурс, чтобы они выполнялись круглосуточно?

Задача следующая: есть URL, на который требуется с определенной периодичностью отправлять POST-запросы 24/7. Набросал код на JS и запустил на ноде, все работает. Но свой компьютер постоянно включенным держать не могу. Первая идея - арендовать виртуальный сервер и отправлять запросы с него, но в серверной разработке я полный ноль. Арендованный виртуальный сервер у меня есть, но использую я его только для тестов фронтенда, с серверными скриптами ни разу не работал. Есть ли вообще такая возможность? Подскажите направление куда копать.
Исправление конфигурации OPcache ускорило работу PHP-приложения в 3 раза

Правильное управление OPcache при атомарных деплойментах позволило:

🔸Ускорить приложение в 3 раза.
🔸Снизить нагрузку на CPU в 10 раз.
🔸Сохранить сотни дней на время загрузки для пользователей.

Проблема
При деплойментах с символьными ссылками OPcache продолжает кэшировать файлы предыдущих релизов, заполняя память. Это снижает эффективность кэша.

Решение
Сбрасывать OPcache при каждом деплойменте с помощью cachetool. Это гарантирует, что файлы нового релиза будут кэшироваться заново.

Настройки OPcache
opcache.validate_timestamps=0 — отключить проверку временных меток.
opcache.file_update_protection=0 — мгновенное кэширование новых файлов.
Настроить объем памяти (opcache.memory_consumption) и количество файлов (opcache.max_accelerated_files) для ваших нужд.

Мониторинг
Добавьте ключевые метрики OPcache (свободная память, hit rate) в систему мониторинга. Это поможет выявлять проблемы и оптимизировать работу.

@phpquiz