Ответы пользователя по тегу PHP
  • Оптимальная конфигурация для сервера?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Если вопрос поставлен таким образом - то current stable, то есть PHP 7.2 и MariaDB 10.2.
    Главное - убедиться, что ваш код работает с ними как положено.
    Ответ написан
    Комментировать
  • С какими ключами запускать "composer install" на продакшн?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Level 1: dump-autoload -o и --optimize-autoloader это одно и то же.
    Level 2A: dump-autoload -a и --classmap-authoritative это одно и то же.
    Level 2B: dump-autoload -acpu и --apcu-autoloader это одно и то же.

    Используется либо Level 1, либо Level 2A, либо Level 1 + Level 2B (как в вашем случае). Для прода лучше 2A или 1+2B.
    Ответ написан
    Комментировать
  • Как решить проблему с Notice?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Если совсем по полочкам раскладывать, то:

    - Ваша строчка 9 проверяет не равны ли captcha в $_POST и rand_code в $_SESSION.
    - Ваша строчка никак не проверяет, чтобы эти переменные существовали / были определены, поэтому когда их нет - PHP информирует вас об этом (Notice) - прямым текстом говорит, что в упомянутых массивах нет таких индексов (элементов).
    - Чтобы устранить PHP Notice, необходимо всегда проверять, заданы ли необходимые переменные:

    1. В самом простом случае:
    if ( 
        ( isset( $_POST['captcha'] ) && isset( $_SESSION['rand_code'] ) ) // переменные / индексы определены
        && $_POST['captcha'] != $_SESSION['rand_code'] // собственно, сравнение значений
    ) {
        // остальной код
    }


    2. В реальных условиях чаще всего это происходит в контексте функций / методов и когда идет ряд проверок, принято использовать подход "fail early" (вариации - quit early, bail out early) – проверки идут не вложенными, а одна за одной, наиболее ожидаемые - первыми. Пример аналогичного фрагмента кода с учетом этой практики:
    function some_method_name() {
    
        // Если индексы не существуют или они приводятся к false - выходим из логики
        if ( empty( $_POST['captcha'] ) || empty( $_SESSION['rand_code'] ) ) {
            return; // может быть return false и тд - зависит от конкретной реализации
        }
    
        // Этот код выполнится только если предыдущая проверка прошла успешно и оба индекса имеют значения с которыми можно работать дальше
        if ( $_POST['captcha'] != $_SESSION['rand_code'] ) {
            // остальной код
        }
    }
    Ответ написан
    Комментировать
  • В чем причина ошибки в PHP7?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    1. Не вижу необходимости помещать свойство объекта/класса в дополнительную переменную. Вместо:
    $st = $item->timestamp;
    if(time() < $st){

    достаточно:
    if( time() < $item->timestamp ) {

    2. В PHP exit - это конструкт, и если в него не передается параметр, скобки необязательны (принято не указывать их): вместо exit(); достаточно exit;

    3. Для выхода из цикла необходимо использовать break. Разница в том, что exit прекращает выполнение скрипта вообще, break - только выходит из цикла, прекращая дальнейшие итерации:
    if( time() < $item->timestamp ) {
        break;
    }


    4. Возможно, вам вообще нужно просто прекратить логику в текущей итерации и перейти к следующей итерации (скипнуть текущий элемент в итерации) - для этого есть continue:
    if( time() < $item->timestamp ) {
        continue;
    }
    // тут остальная логика в итерации цикла, 
    // при выполнении условия и вызове continue; эта логика для текущей итерации не будет выполнена, 
    // произойдет переход к следующей итерации цикла
    ...


    5. Уточните, вам таки из цикла выйти надо (перестать проверять данные в следующих итерациях), или же прекратить выполнение всего скрипта?

    6. Что касается "почему такая конструкция не работает":

    – ваш дамп, это значения $item->timestamp?
    – вы уверены что условие проверки верное, в вашем коде текущий unix timestamp должен быть меньше $item->timestamp, то есть последний должен содержать timestamp в будущем. Рискну предположить, что на самом деле вам необходимо:
    if( $item->timestamp < time() ) {
        continue;
    }
    Ответ написан
    Комментировать
  • Какие есть курсы по Unit тестированию?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Ответ написан
    Комментировать
  • Как исправить ошибку php?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Это ошибка PHP, в коде (PHP WARNING:):
    "array_keys() expects parameter 1 to be array, null given"


    Ошибка говорит о том, что в функцию array_keys() первый параметр который передается является null, а не массивом. Происходит это в строчке 118 файла /site/backend/Controllers/api/v1/settings.php.

    Научитесь читать текст ошибки целиком. В них же все написано, черным по белому.
    Ответ написан
    2 комментария
  • Как сделать древовидные комментарии?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    1. В структуре БД понадобится колонка "parent_id":

    ID - автоинкремент, уникальный ID комментария
    parent_ID - уникальный ID родительского комментария
    object_ID - уникальный ID страницы/записи/объекта, к которому комментарий относится
    ... - остальные колонки

    2. Как выводить деревья знает гугл.
    Ответ написан
  • Как прикрепить файл картинку при отправке сообщения?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Раз уж вы тег WordPress поставили, и сайт у вас на нем - то делайте все как положено. Почитайте про работу с ajax, загрузку файлов и отправку писем с вложениями:

    https://wp-kama.ru/id_2018/ajax-v-wordpress.html
    https://wp-kama.ru/id_9026/jquery-ajax-zagruzka-fa...
    https://codex.wordpress.org/Function_Reference/wp_...
    https://developer.wordpress.org/reference/function...

    Грубо говоря, WP из коробки предоставляет вам возможность обрабатывать ajax-запросы с фронта, загружать файлы (одновременно проводя проверку загружаемых файлов), отправлять письма с вложениями.
    Ответ написан
  • Как получить ссылку на определённую страницу?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    echo get_permalink( get_page_by_path( 'portfolio' ) );
    Ответ написан
    1 комментарий
  • Как получить список страниц с своей структурой?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Для всех древовидных данных WordPress предоставляет Walker'ы. Наиболее популярный (и наиболее часто используемый) - это Walker_Nav_Menu. Но есть также Walker_Page, который используется как раз в вашем случае.
    Ответ написан
    Комментировать
  • Где найти эти методы и свойства?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    +1 к ответу Max Medar, дополнительно - используйте полноценный IDE (например, PhpStorm). Иногда достаточно просто начать вводить логичное название функции, чтобы убедиться, что она внезапно существует:

    59f5cc2062599968188840.jpeg

    Ну и да, главный источник знаний - код ядра WP. Открываете и изучаете, пофайлово, или помодульно. Или как удобнее.
    Ответ написан
    Комментировать
  • Как создать собственный, простой аналог языковой конструкции (вроде endwhile;)?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Позвольте уточнить, чего вы пытаетесь добиться?

    Рискну предположить, что вас задалбывает часто писать одно и то же (в данном случае - кастомный Loop в WordPress). Это можно решить 2мя методами:

    - написать свой loop builder, которому только параметры передать, а он остальное соберет сам.
    - настроить live templates (это в PhpStorm, в других IDE есть аналоги) и использовать их. Например у меня в PhpStorm много таких live templates, я к примеру пишу ??loop, нажимаю tab и получаю сразу весь код цикла.
    Ответ написан
    2 комментария
  • Есть ли изначальная функция регистрации пользователей у различных CMS?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    если я создам что-то вроде блога на WP, то можно ли как-нибудь сделать регистрацию и чтобы авторизированные пользователи могли от себя писать комментарии и оставлять посты?

    WordPress изначально как бы задуман как блог, и функционал от этого пляшет. Регистрация и авторизация есть по умолчанию. Комментарии по умолчанию. Для написания постов достаточно пользователям выставлять роль author. Но все это будет делаться в самой админке WP (правда пользователи с ролями ниже администратора будут видеть не всю админку, а только ту часть, куда им разрешен доступ). Если вам нужен "личный кабинет" на фронте, то его придется либо пилить самому (как это сделали в WooCommerce), либо подбирать плагин. Плагинов для этого дела - масса, глаза разбегаются. Как платных, так и бесплатных.
    Ответ написан
    6 комментариев
  • Как удалить циклическую ссылку с логотипа?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    <?php if ( is_front_page() || is_home() ) : ?>
        <img src="">
    <?php else : ?>
        <a class="logo" href="<?php echo esc_url( home_url( '/' ) ); ?>">
            <img src="">
        </a>
    <?php endif; ?>
    Ответ написан
    Комментировать
  • Как дать права на добавление/редактирование постов кастомного типа, для подписчиков из админки?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Если custom post type зарегистрирован с capability "post", тогда ваши cpt будут использовать те же разрешения, что и посты, что вполне логично. Если же вы сгенерируете custom caps при регистрации вашего custom post type, то это позволит настроить доступ только к нему, исключая доступ к страницам и обычным записям. Я бы даже роль отдельную для этого сделал.

    Подробнее читайте в документации в разделах Roles and Capabilities, а также по функции register_post_type, параметр capability (и map meta cap).
    Ответ написан
    4 комментария
  • Правильная ли у меня структура для темы Woocommerce?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Вы не совсем уловили иерархию шаблонов WP. Файл index.php нужен не только потому что "без index.php тема не работает", а потому что это основной fallback шаблон, который используется если не обнаружен более подходящий (более специфичный).

    В вашем текущей конфигурации абсолютно все страницы сайта будут использовать index.php, только кроме архивов товаров. WooCommerce темплейт archive-product.php используется для отображения страниц с товарами (все товары, товары в категории и тд) включая главную страницу магазина (не сайта!), которая обычно example.ru/shop.
    Ответ написан
  • Как написать сервис определение скорости загрузки сайта?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Есть вот такой шикарный сервис - https://apex.sh/ping/
    Правда, сейчас там уже нет бесплатных аккаунтов, но если подходить к делу серьезно, то этот сервис стоит каждый доллар. Есть много аналогичных сервисов, гугл в помощь. У многих есть базовые бесплатные аккаунты.

    Для более серьезного мониторинга и анализа на стороне бекенда есть https://newrelic.com

    Базовые показатели скорости загрузки можно отслеживать и с помощью Google Analytics. Отдельно можно отслеживать только аптайм, например, с помощью https://uptimerobot.com
    Ответ написан
  • Хранение html разметки в файлах локализации?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Хорошо ли? Спорный вопрос, но насколько мне известно, другого варианта из коробки нет. Главное соблюдать 2 правила:

    1. Избегать разметки как таковой (div, header и тому подобное) в файлах перевода. Ограничиваться inline-элементами форматирования, такими как strong, sub и тд. Если приходится вставлять большой кусок c более общими тегами, вероятно его стоит разбить на более мелкие фразы.
    2. Не забывать выводить правильно с помощью {!! $string !!}
    Ответ написан
    Комментировать
  • Как добавить условие, при котором которое будет исполнять функцию через раз?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    function ads_h2( $content ) {
    
    	// Хорошая практика, называется "return early"
    	if ( ! is_single() ) {
    		return $content;
    	}
    
    	// Заготовили код рекламы
    	$ad = '[AD]';
    
    	// Инициализировали счетчик
    	$count = 1; // 0 или 1, по ситуации
    
    	// Делаем замену через коллбек
        $content = preg_replace_callback(
            '#<h2(.*?)</h2>#',
            // С помощью use передаем в замыкание дополнительные параметры
            function( $matches ) use ( &$count, $ad ) {
                // Увеличиваем счетчик
                $count++;
                // Если число четное, добавляем рекламу
                if ( $count % 2 == 0 ) {
    	            return '<div class="ads_content">' . $matches[0] . $ad . '</div>';
                // Если нечетное - ничего не делаем
                } else {
                    return $matches[0];
                }
            },
            $content
        );
    
    	// Вернули измененный контент
    	return $content;
    }
    add_filter( 'the_content', 'ads_h2' );


    Бонус

    Если менять цифру в if ( $count % 2 == 0 ) { вместо 2 на, скажем, 3 или 4, то реклама будет выводиться, соответственно, в каждом 3м или 4м подзаголовке.
    Ответ написан
    2 комментария