Задать вопрос
  • Как сделать круглые углы в Photoshop?

    @Tolnik
    ПД
    Нарисовать инструментом "Перо" контур.
    На верхнем слое разместить картинку.
    Зажать клавишу Alt и кликнуть по границе между слоями.
    Изображение с верхнего слоя-картинки останется только в контуре, который можно редактировать векторными инструментами.
    Или смотри анимированную гуфку:
    691ef6dc3772d126123085.gif
    Ответ написан
    Комментировать
  • Подключние к базе данных из класса - насколько правильно?

    nokimaro
    @nokimaro
    Меня невозможно остановить, если я смогу начать.
    С ответами выше полностью согласен, DI через конструктор, авто-резолв зависимостей, возможно даже сервис контейнер с биндингами - это правильно, явное лучше не явного и тд.

    Но я предлагаю не мучаться, а просто сделать singleton-обертку над PDO
    И вызывать её там где нужно нафигачить запросы к БД

    class DB
    <?php
    class DB
    {
        private static $instance = null;
        private $pdo;
    
        private function __construct()
        {
            $host = 'localhost';
            $dbname = 'your_database';
            $username = 'your_username';
            $password = 'your_password';
            $charset = 'utf8mb4';
    
            $dsn = "mysql:host=$host;dbname=$dbname;charset=$charset";
            $options = [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            ];
    
            $this->pdo = new PDO($dsn, $username, $password, $options);
        }
    
        public static function getInstance()
        {
            if (self::$instance === null) {
                self::$instance = new self();
            }
            return self::$instance->pdo;
        }
    
        private function __clone() {}
        private function __wakeup() {}
    }


    class Data 
    {
        public function __construct($param1, $param2)
        {
             // Получаем PDO напрямую
            $this->db = DB::getInstance();
        }
    
        public function example()
        {
            // $query = $this->db->query("SELECT * FROM table");
            // $query->execute();
    
            // $stmt = $this->db->prepare("...");
        }
    }


    Вариант пробросить PDO через конструктор всё ещё останется, если поймете что оно вам нужно
    А так просто получаем глобальный доступ к инстансу PDO из любого места в коде
    Ответ написан
  • Что думаете о Livewire и Inertia.js?

    @SaintJohnny
    Может кому-нибудь мой опыт пригодится, страница хорошо ранжируется, значит читают.

    Испробовал все технологии.
    Даже для среднего проекта типа Интернет-магазин + товарный учет, где уже нужен удобный и отзывчивый интерфейс средствами Laravel (Blade) не обойтись, нужен js.
    Начал внедрять Livewire , сначала думал, вот он Грааль, но оказалось такой костыль, и если что-то не так применить, сайт тупил не по-детски. Местами пришлось переписывать в ущерб SOLID, где-то сломалась логика, и если ошибка отследить сложно. А через пару месяцев вообще сложно найти, где что и как работает. С ужасом взглянул на это безобразие и решил на еще не сданном проекте перейти на Inertia (причем, по первой, часть разделов работали на старом интерфейсе Blade + Livewire , остальная на Inertia+Vue)
    Единственно где оставил Livewire - это несколько общих компонентов на клиентской части, где Inertia+Vue не применишь, т.к. SEO. Здесь Livewire идеально вписался. На Livewire сделал виджеты - Корзина, Избранное, Поиск, Обратная связь и еще пару.

    А админку всю перевел на Inertia на Vue3. Это в принципе тот же Vue, только без роутинга, авторизации laravel и других удобных вещей.
    Если пилить проект в одного, то Inertia это лучшее решение, так как ускоряет разработку, чем Laravel + Vue (React)
    Единственное нельзя использовать связи моделей как в Blade, т.к. Inertia не передает все данные, надо либо использовать with, либо самому делать конвертацию объектов и связей в массив (JSON).
    По мне, лучше самому конвертировать, так больше контроля и если вдруг перейти на чистый Vue3, то переделывать придется мало.
    Ответ написан
    Комментировать
  • Можно ли как-то в switch запихнуть две переменных?

    @AUser0
    Чем больше знаю, тем лучше понимаю, как мало знаю.
    Ещё вариант:
    switch ("{$i}:{$j}") {
        case "0:1":
            echo "i=0, j=1";
            break;
    }
    Ответ написан
    Комментировать
  • Как сделать опциональные поля в DTO?

    delphinpro
    @delphinpro Куратор тега PHP
    frontend developer
    ну как вариант в методе prepareForValidation() форм-реквеста заполнять недостающие поля нулями
    Ответ написан
    Комментировать
  • В чем преимущества Route Model Binding?

    vfreelancer
    @vfreelancer
    php
    с коллегами не согласен. это магия, затрудняет чтение кода. преимущество в простых случаях - нет лишней строки
    Ответ написан
    5 комментариев
  • Как достать переменную из объекта?

    usdglander
    @usdglander Куратор тега PHP
    Yipee-ki-yay
    eval($row->CustomSettings);
    var_dump($custom_settings['ru']);

    :)
    Ответ написан
    Комментировать
  • Как сделать прогресс бар скачивания одного файла?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    нужно создать потоковый контекст и использовать stream-notification-callback (см. пример).

    Функция будет вызываться в процессе загрузки / выгрузки файла, сообщая о количестве переданных байтов. Это то, что нужно для отрисовки прогресс-бара.
    Ответ написан
    2 комментария
  • Как вы храните глобальные переменные Laravel приложения?

    theillarionov
    @theillarionov
    Люблю frontend (иногда это даже взаимно)
    У меня глобальные переменные, как правило, содержат в себе какие-то генеральные настройки и я храню их в .env
    Но есть ещё вариант просто с созданием конфигурационного файла.
    Разница в том, что .env, как правило, находится в .gitignore. Если вам нужны какие-то глобальные переменные, одинаковые для всех разработчиков, то разместите их в /config.
    Ответ написан
    Комментировать
  • Как упорядочить список ip адресов?

    flapflapjack
    @flapflapjack
    на треть я прав
    https://ip-calculator.ru/aggregate/

    тут это всегда делал. Удобно и быстро, в любом порядке жрёт адреса и агрегирует их в подсети
    Ответ написан
    Комментировать
  • Можно ли разрешить просмотр только при Ajax-подгрузке страницы?

    zkrvndm
    @zkrvndm
    Архитектор решений
    Делай так:
    <?php
    
    // Если мы получили GET-запрос:
    
    if ($_SERVER['REQUEST_METHOD'] == 'GET') {
    	
    	header('Location:/', TRUE, 301); // Переадресуем на главную
    	
    }
    
    // Если мы получили POST-запрос:
    
    if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    	
    	// Выводишь данные, которые нужны
    	
    }

    Когда делаешь аякс-запрос, просто поменяй тип запроса с GET на POST.
    Ответ написан
    Комментировать
  • Как добавить в .gitignore такие файлы как gulpfile.js, package-lock.json и package.json?

    sergey-kuznetsov
    @sergey-kuznetsov Куратор тега Git
    Автоматизатор
    Такие файлы добавляются в .gitignore так же, как и любой другой файл.
    Но, подозреваю, что вопрос в другом. Хочется чтобы файлы исчезли из проекта?
    Ты видишь, что файл никуда не исчез и сделал вывод, что файл не добавлен в игнор. Но это не так.
    По сути .gitignore тебе совершенно не нужен, потому что добавление файла в игнор не удалит его автоматически из репозитория, если он ранее уже был добавлен в отслеживаемые. Этот файл нужен только чтобы случайно не добавить в репозиторий лишнее. Но даже он не помешает нам добавить любой файл в репо командой git add файл

    Когда не хочешь видеть файл в репо, просто удали его физически и сделай коммит.

    Если же файл нужен в рабочем каталоге, но ты не хочешь его светить в репозитории, то удали файл только из индекса командой git rm --cached имя_файла и закоммить это.
    Ответ написан
    1 комментарий
  • Как сделать открытие случайной страницы на сайте?

    anton_reut
    @anton_reut
    Начинающий веб-разработчик
    <a class="btn" href="example.com/index.php?id=<?php echo rand(1, 4000); ?>"> КНОПКА </a>
    Ответ написан
    Комментировать
  • Как очищать текст в php?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Никак не очищать.

    На самом деле этот вопрос встречается довольно часто. Вот например популярный ответ на Stack Overflow, который подробно разбирает этот распространённое заблуждение: https://stackoverflow.com/a/3126175. И основная мысль там:

    Понятие такой генерализованной "очистки данных" изначально бессмысленное и вредное.

    Особенно такой вот индусской функцией, которая сама по себе - пример редкого идиотизма: сначала заменяем символы < и > на HTML сущности... а потом бодро пытаемся вырезать HTML теги. Которых к этому моменту в тексте не останется ни одного!
    Или функция stripcslashes, которая здесь вообще ни к селу, ни к городу. Если я хочу написать сочетание \n, то с какой стати эта функция будет заменять его на перевод строки?
    Всё что можно оставить из этого безумного набора - это trim(). Да и то не всегда. Как правильно заметил Rsa97, могут быть случаи, когда лидирующие пробелы имеют значение, например, при выводе форматированного кода. Кстати, этим как раз грешит Хабр. Если запостить код с отступами, то первый будет "съеден"!


    Очистка

    Любая "очистка" (хотя правильнее говорить про форматирование), имеет смысл только в определённом контексте.
    И поэтому "очищать" надо только адресно, строго перед использованием в том или ином конкретном случае.

    Например, базе данных ни жарко, ни холодно от наличия HTML тегов.
    А проблемы могут начаться только при выводе данных в HTML. Но если мы будем предотвращать эти проблемы заранее, то просто попортим кучу данных. Поэтому форматировать данные для использования в контексте отрисовки HTML следет строго перед этой отрисовкой. То есть при выводе.
    Что и делают все популярные РНР шаблонизаторы автоматически.
    То есть вручную колупаться с "очисткой" вообще не нужно.

    Больше того, "очистка" HTML поможет данным, выводимым в яваскрипт, как мёртвому припарки. То есть опять же - всегда надо понимать, в какой именно контекст мы выводим данные, и форматировать соответствующим образом. В частности любые данные передавать в яваскрипт только через json_encode()

    И таких контекстов неисчислимое множество. Например, если мы используем переменную для передачи параметров в консольный скрипт, то надо обязательно обрабатывать её через escapeshellarg(). Если в регулярку - то preg_quote(). Имя файла для инклюда из переменной (хотя так делать вообще не стоит) надо хотя бы обрабатывать через basename(). И так далее.

    Валидация

    Если же наличие HTML тегов в поступающих данных противоречит техническому заданию, то надо заниматься не "очисткой", а валидацией: проверить регулярным выражением, есть ли в строке HTML теги. И если есть, то вернуть пользователю с сообщением об ошибке.

    Защита БД

    И кстати, по поводу "использую pdo".
    На всякий случай уточню, что само по себе использование PDO не защищает ни от каких проблем
    Важно помнить, что защита - это когда в базу данных отправляется строго константная строка запроса, полностью на 100% составленная из значений, прописанных в коде РНР, и в ней не используется ни одно значение, пришедшее в код извне. Причем PDO помогает здесь только наполовину, позволяя использовать в запросе подстановки вместо самих данных.
    Но при этом для всех остальных частей запроса - например имен полей - у ПДО нет никакой защиты и её надо организовывать самостоятельно. Либо проверяя по белому списку, лабо, по крайней мере, прогоняя через регулярку.
    Ответ написан
    13 комментариев
  • ООП в php - не понимаю объекты, неправильно передаю ссылки?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Здесь неправильно не то что всё, а даже больше.
    Потому что ёще до того как вы взялись писать этот "класс", не выучив даже базовый ООП синтаксис, код вашей "функции" уже был очень плохой.

    Я сейчас напишу минимально приемлемый вариант, но повторять его не надо. Потому что всё равно непонятно будет.
    Надо забыть временно про классы и учить базовый синтаксис РНР. Просто потому что сначала надо выучить базовые понятия - работу с БД, обработку ошибок, разделение ответственности:
    - работа с переменными в запросе ведётся через параметризованные запросы
    - код класса не должно тошнить прямо на экран сообщениями об ошибках
    - метод getArray не должен возвращать объект класса mysqli_result. он должен возвращать массив
    - код, который будет в дальнейшем работать с результатом вызова метода getArray, не должен ничего знать про базу данных

    Про сам же код ООП надо хотя бы один раз посмотреть его в учебнике, а не писать на основе чистой фантазии.
    class CProducts
    {
        private $link;
        public function __construct(mysqli $link) {
            $thi->link = $link;
        }
        public function getArray($lim) {
            $query = "SELECT * FROM products ORDER BY DATE_CREATE DESC LIMIT ?";
            $stmt = $this->link->prepare($query);
            $stmt->bind_param("s", $lim);
            $stmt->exeсute();
            $result = $stmt->get_result();
            return $result->fetch_all(MYSQLI_ASSOC);
        }
    }
     
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $db = new mysqli($host, $user, $pass, $dbname);
    $db->set_charset('utf8mb4');
    $db->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, 1);
      
    $product = new CProducts($db);
    $result = $product->getArray(3);
    Ответ написан
    Комментировать
  • Как доработать код?

    @Vitsliputsli
    Ничего страшного, допишите еще один case и метод, и все будет нормально. Да, это нарушает принцип, но все так делают, просто хрен кто признается. Не пытайтесь здесь вкрячить какого-нибудь монстра, сложный код - это потенциальные ошибки, если возможно написать просто, так и нужно сделать.
    Принципы - они принципы, а не законы, надо следовать не букве, а смыслу. Принцип открытости и закрытости оберегает нас от ошибок и дополнительных затрат на тестирование кода, который вроде бы и так уже работает и хорошо себя зарекомендовал. Т.е. если бы у вас был один метод и вы там внутри как-то хитро разруливали работу с разными типами и при добавлении нового типа изменяли бы его - это было бы ужасно. В текущей реализации, вам нужно будет добавить новый метод (это не изменит поведение класса до вмешательства), и добавить новый путь при использовании нового типа - да, вмешательство, но оно минимально. Если умудритесь накосячить здесь, то вас уже никакие принципы не спасут.
    Если же у нас, что-то гораздо более сложное, либо класс физически недоступен для изменений, или он уже вовсю используется, а новый тип нужен только для конкретной реализации, то, пожалуйста, есть наследование. Наследуете класс, в потомке добавляете метод и заменяете метод, выполняющий перенаправление (не забывайте, что есть вызов parent). Это будет полностью соответствовать принципу.
    Но я бы больше уделил внимание тому, почему мы ориентируемся для выбора метода на внутреннее свойство, точно ли это должны быть методы, а не отдельные классы. И вполне может быть получится так, что все эти танцы с бубнами не нужны.
    Ответ написан
    Комментировать
  • Как можно сделать личное расширение для файла, чтобы оно работало как exe?

    @urm0m8f
    из под админа в командной строке
    assoc .qnahabr=myexefile
    ftype myexefile="%1" %*

    также, абсолютно равноценны расширения *.pif *.exe *.com.
    *.scr - почти, там ключ /S добавляется.
    c:\>assoc .exe
    .exe=exefile
    
    c:\>ftype exefile
    exefile="%1" %*
    
    c:\>assoc .pif
    .pif=piffile
    
    c:\>ftype piffile
    piffile="%1" %*
    
    c:\>assoc .scr
    .scr=scrfile
    
    c:\>ftype scrfile
    scrfile="%1" /S
    Ответ написан
    Комментировать
  • Что думаете о Livewire и Inertia.js?

    agoalofalife
    @agoalofalife
    Team Lead
    И тот и другой инструмент под свой круг задач вполне подходит.
    Livewire - как вам ответили выше, хорошо подходит mvp, небольших сайтов, где нет большой нагрузки и грандиозных планов.
    Хотя кто-то берет на себя риски и делает все на нем. Из подводных камней, это у вас связаны руки в js, так же на каждое действие, он будет слать запрос на сервер. То есть написали букву в input, запрос на сервер(хотя можно оптимизировать, но тем не менее), в итоге получается такой оверхед на все.
    Стоит иметь в виду о смеси ответственностей, точнее livewire будет вас постоянно склонять к этому, так как в классах php у вас постоянно логика фронта.
    Еще могут быть не очевидные проблемы, при синхронизации данных, и вам надо будет подставлять задержки.
    У меня была проблема с загрузкой файла, в кратце есть две настройки в вашем php.ini и отдельно в файле livewire, в каждом стоит свое максимальное значение размера файла.
    Так вот- грузил я картинку по событию change, после загрузки была написана валидация, в кратце файл не грузился и в блок с валидации было пусто.
    Проблема заключалось в том, что livewire не как об этом не сообщал и не намекал, просто не грузил файл и валидация не проходила.
    Так что будьте готовы решать такие нюансы.
    Мой субъективный опыт получился двоякий, с одной стороны мне понравилась скорость, с другой стороны что-то не работает, возможно это временно пока все шишки не набьешь.

    С Inertia опыт пока только теоретический, но он уже ближе к нормальному стеку. Просто вам не надо думать о роутинге, api, вывода ошибок.
    Врать не буду, ибо фраза:
    В теории нет разницы между теорией и практикой. А на практике есть

    Поэтому я дополню свой ответ позже - если посчастливиться его попробывать

    Вывод
    Рекомендую попробовать оба варианта несколько раз, тогда вы составите для себя полноценное мнение об этих инструментах.
    Любой продукт который поддерживается и используется сообществом - уже лучше N фреймворка который знаете вы и еще двое людей.
    Повторюсь еще раз, имеет место быть, так как для всех копеечных проектов которые живет два понедельника - писать spa - очень дорогое и бессмысленное удовольствие.
    Ответ написан
    Комментировать
  • Как переадресовать реферальую ссылку php?

    SagePtr
    @SagePtr
    Еда - это святое
    Если средствами .htaccess, судя по тэгу, то как-то так:
    RewriteEngine On
    RewriteCond %{QUERY_STRING} ^i=\d+$
    RewriteRule ^$ https://dom.com/ [R=301,L,QSA]
    Ответ написан
    Комментировать