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

    php666
    @php666
    PHP-макака
    Не надо ничего придумывать.
    МВС модель давно придумана и успешно функционирует.
    Берешь Ларавель и изучаешь.
    Ответ написан
    4 комментария
  • Есть ли какие-то методы написания кода, когда надо смешать php и html в одной строке?

    php666
    @php666
    PHP-макака
    Излюбленная тема умников всех времен и народов, когда поднимается тема о смешении php и html - советовать на каждый чих шаблонизатор. При этом, почему-то умалчивается, что любой шаблозатор в итоге создаёт туже самую смесь из php и html.

    Шаблонизатор - это просто пхп написанный на пхп с синтаксическим сахаром. И использовать его нужно тогда, когда это необходимо. Наследование шаблонов, эскейпинг и, в целом, когда в этом есть НЕОБХОДИМОСТЬ, что бы не писать хэлперы обработки вывода данных.

    Если же речь идёт о каком-то локальном решении, то нужно использовать один шаблонизатор и имя ему - PHP.
    Для этого в языке есть такая вещь, как короткие теги вывода <?=$var?> и альтернативный синтаксис управляющих структур, который идеально ложится на html как инструмент для адекватного восприятия логики отображения. Кроме этого, можно задействовать функции буферизации вывода и получить легковесное решение.
    Ответ написан
    2 комментария
  • Как сделать роутинг с динамической uri?

    php666
    @php666
    PHP-макака
    Я попросту не могу понять принцип, как объяснить роутеру, какая часть будет динамичная.

    $routes = [
        ['~/user/([0-9]+)/?~', ['id'], UserController::class, 'showUser'],
        // ...
    ];

    дальше, имея представление о функции preg_match и управляющих конструкциях языка, сам додумаешься?
    Ответ написан
    Комментировать
  • Насколько актуален чистый PHP?

    php666
    @php666
    PHP-макака
    Отвечу как автор того самого обширного ответа.

    Первое. В голове у тебя тотальное непонимание. Вопрос твой звучит примерно так же, как "можно ли быть хирургом не зная анатомию человека и не закончив 5 лет мед института?". Естественно нет.

    Есть ли сейчас смысл в оттачивании чистого PHP
    Язык всегда первичен. Да.

    Далее. Вот эта фраза
    если мне +- хватает понимания, как работает та же Ларавел?
    Ты серьезно думаешь, что у тебя "хватает понимания", как работает фреймворк? Больше не повторяй вслух эти слова. Никогда. Особенно на собеседовании. Иначе собеседующие тебя похоронят за плинтусом.

    Может, при возможности стоит обратить внимание на другой язык(Го, шарп, нода)?
    Сегодня разговаривал с HR-ом, дословно: php-шников и фронтов много. Больше остальных. Спрос на другие языки - go и питон - там низкая конкуренция. Не могу ей не поверить, т.к. php существует более 20 лет и за это время в отрасль вкатилась куча людей. Откровенно говоря, очень скоро значительный % пхп-макак пойдет в такси, включая меня. Конкуренция, судя по собеседованиям - адовая. Спрашивают сам язык и ещё 250 сопутствующих технологий.

    не рискую пока идти на собеседования потому что хочу закрыть чеклист: несколько проектов в портфолио на чистом PHP, laravel; подучить JS с Аяксом; Добить тестирование, а также чуть разобраться с докером, линуксом и теоретической частью этих ваших интернетов.
    мертвому припарка. Ты никогда в "домашних условиях" не получишь боевой опыт. Лучше иди работай за "ничего", больше пользы будет.
    Ответ написан
    1 комментарий
  • Как часто нужна модель MVC?

    php666
    @php666
    PHP-макака
    Если я сделаю, условно, 10 таких одинаковых проектов, будет ли от этого толк больше, чем от 10 аналогичных проектов на Ларавел?
    Не будет.

    Сейчас тенденция такая: работодателю НЕ НУЖНЫ теоретики, нужны практики на том, что востребовано. Точка. Я тебе это говорю как человек, писавший свой фреймворк в свободное время (по желанию от нефигделать) на протяжении нескольких лет. Это абсолютно пустая трата времени, никто это не оценит, а в некоторых случаях даже будут косо смотреть - век программистов прошёл, сейчас век знающих "либы". Лучше потратить это время на освоение того же Laravel.

    который просто будет писаться заново каждый раз с какими-нибудь косметическими (и не очень) изменениями
    Это у тебя будет одной из самых сложных задач - поддержка актуальности. Твое решение будет глобально переписано минимум 125 раз, тебе необходимо будет делать приложение отдельным композер-пакетом-зависимостью, это усложнит абсолютно весь процесс и ты просто не напишешь эти 10 сайтов. Никогда.

    Приведу реальный пример.
    У меня был фреймворк в составе проекта.
    1. Принял решение вынести фреймворк в отдельную composer-зависимость, написал систему модульности, при которой отдельное приложение - просто набор модулей, а фреймворк устанавливался через композер.
    1.1. В итоге получилось два репозитория: существовавший ранее проект (назовем его "А") и фрейморк.
    2. Принял решение сделать т.н. skeleton (назовем его "B") для будущих задач, т.е. некую болванку для будущих проектов.
    3. Возникла основная проблема - актуализация клиентского кода между проектами "А" и "В" в процессе изменения интерфейсов фреймворка. Любое изменение/дополнение/улучшение в программном коде фреймворка тянуло за собой переписывание клиентского кода в проектах "А" и "В". Не потому, что всё ломалось, а потому, что это предотвращало технический долг и влияло на банальную красоту/чистоту кода.
    3.1. Возникла проблема актуализации ресурсов (css, js) и базовых модулей между проектами "А" и "В". Приложение "В" (skeleton) должно было стать эталоном. В skeleton есть некий базовый набор CSS/JS, правил верстки и готовых модулей. Всё это постоянно совершенствовалось. Эти дополнения хотелось вносить в уже действующий проект "А", но делать это приходилось с кровью и потом, т.к. это была тупая ручная работа из разряда copy-paste, т.к. skeleton ("B") по своей сути - это готовый проект, как "А". И тут это всё нельзя было никак автоматизировать.

    В итоге от скелетона, который планировался как "болванка" для будущих проектов, пришлось отказаться.

    Поэтому твоя идея на базе своего решения клепать 10 сайтов - нежизнеспособна. У тебя банально не хватит времени на разработку фреймворка и актуализацию клиентского кода проектов.
    Ответ написан
    Комментировать
  • Как в условие исключить число?

    php666
    @php666
    PHP-макака
    Советы выше - не универсальны и ведут к дублированию кода.
    Вот более правильный универсальный вариант:

    class Checker
    {
        /**
         * @var mixed
         */
        protected mixed $value;
    
        /**
         * @var int
         */
        protected int $minimalValue = 0;
    
        /**
         * @var array
         */
        protected array $excludeValues = [];
    
        /**
         * Checker constructor.
         * @param mixed $value
         */
        public function __construct(mixed $value)
        {
            return $this->checkValue($value, function() use ($value) {
                $this->value = $value;
    
                return $this;
            });
        }
    
        /**
         * @param mixed $value
         * @return $this
         */
        public function setMinimalValue(mixed $value): self
        {
            return $this->checkValue($value, function() use ($value) {
                $this->minimalValue = $value;
    
                return $this;
            });
        }
    
        /**
         * @param mixed $value
         * @return $this
         */
        public function setExcludeValue(mixed $value): self
        {
            return $this->checkValue($value, function() use ($value) {
                if (!array_search($value, $this->excludeValues)) {
                    array_push($this->excludeValues, $value);
                }
    
                return $this;
            });
        }
    
        /**
         * @return bool
         */
        public function validate(): bool
        {
            return $this->value > $this->minimalValue && !in_array($this->value, $this->excludeValues);
        }
    
        /**
         * @param mixed $value
         * @param callable $callable
         * @return $this
         */
        protected function checkValue(mixed $value, callable $callable): self
        {
            if (!$this->isInteger($value)) {
                throw new \RuntimeException("Value `$value` is not integer");
            }
    
            return $callable($this);
        }
    
        /**
         * @param mixed $val
         * @return bool
         */
        protected function isInteger(mixed $val): bool
        {
            if (!is_scalar($val) || is_bool($val)) {
                return false;
            }
    
            return $this->isFloat($val)
                ? false
                : preg_match('~^((?:\+|-)?[0-9]+)$~', $val) === 1;
        }
    
        /**
         * @param mixed $val
         * @return bool
         */
        protected function isFloat(mixed $val): bool
        {
            if (!is_scalar($val) || is_bool($val)) {
                return false;
            }
    
            $type = gettype($val);
    
            if ($type === "double") {
                return true;
            } else {
                return preg_match("/^([+-]*\\d+)*\\.(\\d+)*$/", $val) === 1;
            }
        }
    }
    
    try {
        echo (int) (new Checker('5'))
            ->setMinimalValue(4)
            ->setExcludeValue(107)
            ->setExcludeValue(107)
            ->setExcludeValue(108)
            ->validate();
    } catch (\Exception $e) {
        echo $e->getMessage();
    }
    Ответ написан
    Комментировать
  • Почему self так работает?

    php666
    @php666
    PHP-макака
    Автор в какой-то раз задает какие-то сверхсложные вопросы. Как выделяется память, как это работает на уровне интерпретации и тп.
    Может стоит подход к изучению изменить?

    Как константы работают при наследовании?
    Константы импортируются в классы потомки?
    ну типа да, на то оно и наследование.
    Ответ написан
    Комментировать
  • Почему не сохраняется присвоенное переменной класса значение?

    php666
    @php666
    PHP-макака
    На этот говнокод невозможно смотреть, у меня кровь из глаз пошла.

    Давай ты для начала
    1. Почитаешь об автозагрузке классов
    2. Перестанешь писать require в методах и почитаешь про внедрение зависимостей.
    3. Перестанешь использовать собаку @ там, где это не требуется. А именно в условии if (@$_REQUEST['select']) , для этого есть функции isset и empty.
    4. Внятно сформулируешь свой вопрос без кучи этого околорабочего кода и напишешь небольшой класс, описав проблемы с геттерами и сеттерами.
    Ответ написан
    4 комментария
  • Очистка кэша php?

    php666
    @php666
    PHP-макака
    Примерно так:
    Запрос вида /css/style.css
    обрабатывается неким контроллером, назовём его контроллер CSS.
    Т.е. если с сервера запрашивается адрес /css/style.css, на самом деле вызывается php скрипт, в который передаётся аргумент, строка "style.css" (гугли mod_rewrite или единая точка входа).

    Далее, в контроллере CSS ты смотришь дату изменения этого файла style.css:

    function getModificationTime($path_to_file)
    {
        return (new Datetime())->setTimestamp(filemtime('/my/style/paths/' . $path_to_file));
    }
    
    $modify_date = getModificationTime('styles.css');


    Далее, в этом контроллере ты проверяешь, пришёл ли от браузера заголовок HTTP_IF_MODIFIED_SINCE (погугли, что это).

    /**
         * Возвращает true, если дата (обычно документа) $data является устаревшей
         * по отношению к HTTP заголовку If-Modified-Since.
         *
         * @param $date \DateTime
         * @return bool
         */
        public static function IfModifiedSince(\DateTime $date): bool
        {
            if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
                $if_modified_since = strtotime(substr($_SERVER['HTTP_IF_MODIFIED_SINCE'], 5));
    
                if ($if_modified_since && $if_modified_since >= $date->getTimestamp()) {
                    return false;
                }
            }
    
            return true;
        }


    если true, считываешь css файл и выплёвываешь его посредством этого контроллера (через echo), отправляя http заголовки, присущие для css ('text/css; charset=utf-8') и заголовок Last-Modified с датой $modify_date в формате "D, d M Y H:i:s \G\M\T"

    если false (файл не изменился) просто отдаешь http заголовок 304

    ----

    этой информации тебе достаточно, что бы самостоятельно всё самому реализовать
    Ответ написан
    Комментировать
  • Какой паттерн использовать для формирования выходных данных?

    php666
    @php666
    PHP-макака
    В laravel есть нечто похожее, не смог найти в документации, забыл как называется. Суть в том, что на каждый ответ, например на ajax-запрос, имеется свой класс, который принимает на вход что-то, а отдает строго оговоренный массив данных, который тупо прописывается в методе, который возвращает результирующий массив.
    Только там не как у тебя в setData() основная работа, а наоборот:
    class foo {
       public function getData() {
          return [
              'key' -> $object->id,
              // ....
          ];
       }
    }


    Но, как мне кажется, это избыточный слой. Почему не отдавать содержимое какой-либо сущьности (объекта, массива данных, коллекции) как есть, полностью?
    Ответ написан
    2 комментария
  • В mysql для быстрого поиска по дате лучше использовать timestamp как int или как date (datetime)?

    php666
    @php666
    PHP-макака
    Сделал базу test
    CREATE TABLE `test` (
      `name` varchar(255) NOT NULL,
      `date_int` int(11) UNSIGNED NOT NULL,
      `date_time` datetime NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    ALTER TABLE `test`
      ADD KEY `date_int` (`date_int`),
      ADD KEY `date_time` (`date_time`);
    COMMIT;


    заполнил значениями дат, от 1970-01-01 00:00:01 до 1970-01-05 11:02:29, с разницей 1 секунда, итого вышло 1 603 869 строк (далее php умер и мне лень было настраивать Maximum execution time).

    Разницы вообще нет, если искать точное соответствие вплоть до секунды:
    SELECT * FROM `test` WHERE date_int = UNIX_TIMESTAMP('1970-01-03 12:12:12')

    id 	select_type 	table 	type 	possible_keys 	key 	key_len 	ref 	rows 	Extra 	
    1 	SIMPLE 	test 	ref 	date_int 	date_int 	4 	const 	2 	NULL

    EXPLAIN SELECT * FROM `test` WHERE date_time = '1970-01-03 12:12:12'

    id 	select_type 	table 	type 	possible_keys 	key 	key_len 	ref 	rows 	Extra 	
    1 	SIMPLE 	test 	ref 	date_time 	date_time 	5 	const 	2 	NULL


    Так что фанатик прав, нехрен для даты использовать числа.
    Ответ написан
    Комментировать
  • Проверка авторизации через COOKIE?

    php666
    @php666
    PHP-макака
    Подсказка:
    https://www.php.net/manual/ru/function.setcookie.php
    https://www.php.net/manual/ru/function.empty.php
    https://www.php.net/manual/ru/function.header.php -> нужно отправить заголовок Location

    сам додумаешься как дальше сделать?
    Ответ написан
    Комментировать
  • Какие можно реализовать мини-проекты на PHP?

    php666
    @php666
    PHP-макака
    Автор, posters тебе правильно сказал - нет никакого смысла делать библиотеки-фреймворки. Этого гамна в гитхабе валом, это все рождается и умирает вместе с программистами. 1 из 100 000 делает какой-то востребованный инструмент, которым пользуются другие разработчики. тут играет роль масса факторов: профессионализм, удача, нужное время и место.

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

    php666
    @php666
    PHP-макака
    1. Не надо писать свой "простой MVC-фреймворк", ты его не напишешь в ближайшие годы, только потеряешь время. Возьми Ларавел.

    2.
    require_once $_SERVER['DOCUMENT_ROOT'] . '/vendor/autoload.php';

    DOCUMENT_ROOT указывается в конфиге сервера, соответственно это не будет работать для localhost/test/doubleTest/, если DOCUMENT_ROOT указан как localhost/

    Обычно DOCUMENT_ROOT в подобных случаях устанавливается явно, вот так, на примере файла по адресу /config/constatnts.php:
    define('DOCUMENTROOT_PATH', dirname(dirname(__FILE__)));

    тут кол-во dirname зависит от глубины вложенности файла.
    При подключении в единую точку входа index.php
    // index.php
    include '. /config/constatnts.php';
    
    echo DOCUMENTROOT_PATH; // правильный doc root

    DOCUMENTROOT_PATH будет содержать реальный document root.

    Cл-но ты можешь расположить проект где угодно, как в localhost/, так и в localhost/test/doubleTest/
    Ответ написан
    Комментировать
  • Почему class_exists() выдает flase при проверке наличия класса если класс есть?

    php666
    @php666
    PHP-макака
    $arr = include "inc/routes.php";
    в методах не должно быть никаких include, никогда. передай значение явно, как угодно:
    $arr = include "inc/routes.php";
    $router = new Router($arr);
    // или 
    $router->setRoutes($arr);


    $routs = '#^'.$routs.'$#';
    почему это здесь? описание роута должно быть уже законченным в твоем файле роутов "inc/routes.php", класс ничего не должен добавлять к регулярному выражению.

    spl_autoload_register() Есть и исправно работает.

    $path = 'inc/classes/'.ucfirst($this->params['controller']);

    Это говнокод все. Никаких директорий inc, никаких classes. Все должно быть оопшно и красиво, никаких require.
    Начинай сразу делать правильно.
    Берешь эту статью и пытаешься сделать автозагрузку стандарта PSR-4 до тех пор пор, пока у тебя не получится. Что бы все лежало в пространстве имён.

    Тебе нужно скачать композер, для windows composer.phar, через консоль запустить создание своего composer.json, в статье той тебе НЕ нужно всё, что относится к " подразделы: classmap, files", придумаешь имя себе (vendorname) и имя пакета своего (myfirstgovnokod) далее, когда всё правильно сделаешь у тебя будет всё как правильно - автозагрузка, возможность устанавливать пакеты из вне и правильный подход.

    Сделаешь - покажешь.

    Вот пример что примерно должно получиться:

    /composer.json
    {
        "name": "vendorname/myfirstgovnokod",
        "require": {},
        "autoload": {
            "psr-4": {
                "Govnokod\\": "src"
            }
        }
    }


    /src/Test.php
    <?php
    namespace Govnokod;
    
    class Test
    {
    
    }


    /index.php
    <?php
    
    include 'vendor/autoload.php';
    
    use Govnokod\Test;
    
    $test = new Test();
    
    print_r($test);
    Ответ написан
    Комментировать
  • Значение @ в php?

    php666
    @php666
    PHP-макака
    Не соглашусь с комментаторами выше. Иногда есть причины для подавления ошибки.
    Вот пример:

    $file = '/g/g/g/g/';
    if (!@unlink($file) && file_exists($file)) {
        throw new \RuntimeException('Failed to delete file ' . $file);
    }


    Тут unlink на несуществующем файле приведет к
    Warning: unlink(/g/g/g/g/): No such file or directory in

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

    Если файл не удалился - выкидываем исключение.
    Ответ написан
    1 комментарий
  • Какие в 2021 есть PHP CMS с базовыми функциями?

    php666
    @php666
    PHP-макака
    Ларавел, к примеру (или Симфони). Выбор не велик.
    Куча пакетов, абстрагирующая тебя от написания велосипедов и позволяющая сконцентрироваться на работе.
    Если говорить о "сразу есть админка", то можно погуглить решения типа https://laravel-boilerplate.com/ - там уже админка, с пользователями и авторизацией. Как очевидный плюс - ты сразу же увидишь, как писать на фреймворке на основе нескольких готовых решений (списки сущьностей, CRUD).
    Ответ написан
    3 комментария
  • Как правильно завершить работу скрипта PHP?

    php666
    @php666
    PHP-макака
    Ответ написан
    Комментировать
  • Какой выбрать mvc?

    php666
    @php666
    PHP-макака
    Laravel, ..... не походят


    WannaCry-D0B2D0B8D180D183D181D18B-2665800.jpeg
    Ответ написан
    Комментировать
  • Как спроектировать фреймворк?

    php666
    @php666
    PHP-макака
    Я понимаю про SOLID там, но если следовать правилу единой ответсвенности, то файлов будет просто целая гора,
    да. так оно и и будет

    Также встает вопрос, например, у меня сейчас маршрутизация а-ля микрофреймворк, чтобы прикрутить MVC надо реализовывать поиск контроллера и вызов метода. Должен ли этим заниматься отдельный класс?
    не надо спрашивать такие вопросы. Если ты что-то пишешь, то должен быть уверен в правильности своей архитектуры. Иначе ты на каждый чих будешь вопрос задавать.

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

    Любой фреймворк сейчас - это совокупность из десятков кубиков, каждый из которых разрабатывался и тестировался десятками, а то и сотнями людей, лучших профессионалов в своей области. Попытки в 21 году написать свой фреймворк, всё равно, что в одиночку спроектировать автомобиль, ЛУЧШЕ, чем мировые аналоги. Аналогия примерно такая же, т.е. это НЕВОЗМОЖНО.

    Не занимайся ерундой.
    Ответ написан
    5 комментариев