Ответы пользователя по тегу PHP
  • Почему слетает кодировка от htaccess?

    @SilverSlice
    Если версия php >= 5.6, то проблема может быть в default_charset.
    Ответ написан
    Комментировать
  • Как выбрать "правильный путь" в PHP?

    @SilverSlice
    1. Modern PHP by Josh Lockhart. Книга от создателя уже упомянутого сайта phptherightway.com. Представляет собой обзор современных возможностей языка и хороших практик разработки.
    2. The Clean Architecture in PHP by Kristopher Wilson. В книге разбираются недостатки лапша-кода, которым грешат все книги для начинающих по php. Рассматриваются SOLID-принципы и некоторые шаблоны проектирования. Приводится пример построения приложения на основе изложенных концепций.
    Ответ написан
    Комментировать
  • Почему composer не может решить зависимости?

    @SilverSlice
    Коротко: используйте только стабильные релизы при указании версий в зависимостях в своих пакетах.

    Подробно.
    В composer есть флаг minimum-stability, который используется для отбора пакетов на основе стабильности при установке. По умолчанию он равен stable, т.е. устанавливаются только стабильные пакеты. Вы можете изменить это поведение, добавив параметр "minimum-stability" в composer.json. Обратите внимание, что этот параметр применяется только к корневому пакету - вашему основному composer.json файлу.

    Что происходит, когда вы вводите команду composer require nullref/yii2-cms:
    • Создается composer.json файл, в котором не определен minimum-stability, поэтому он рассматривается как stable.
    • В корневом пакете у вас определен в зависимостях только один пакет - nullref/yii2-cms, который имеет стабильный релиз - он и начинает устанавливаться.
    • Пакет nullref/yii2-cms имеет в зависимостях пакет nullref/yii2-admin с версией dev-master. Это нестабильный релиз и он не может быть установлен, т.к. в корневом пакете minimum-stability считается равным stable.

    Что можно сделать:
    • Установить minimum-stability в dev в корневом composer.json файле. В этом случае также следует добавить "prefer-stable": true, чтобы по возможности ставились стабильные пакеты.
    • Использовать stability flags, явно указав флаг в корневом пакете: "nullref/yii2-admin": "@dev".
    • Убрать dev-master отовсюду из зависимостей, выпускать релизы и указывать версии любым из доступных способов.

    И в заключение привожу ссылку на статью с подробным объяснением minimum-stability.
    Ответ написан
    1 комментарий
  • Создание своего веб-проекта - где найти практическую часть, что почитать?

    @SilverSlice
    К сожалению, книг по php подобного рода я не встречал. Если у вас есть желание самостоятельно реализовать что-либо интересное, не изучая предварительно талмуды по каждой отдельной технологии, могу порекомендовать вам книгу Пьюривал Сэмми - «Основы разработки веб-приложений». Это современное введение в веб-разработку для совсем новичков. На протяжении книги разрабатывается приложение «список задач»: кратко описываются html, css, javascript, jquery. В качестве серверной стороны там выбран node.js, но там нет ничего сложного. Вместе с тем рассказывается о noSQL, git, vagrant, развертывании приложения и рефакторинге. Книга небольшая по объему и подходящая для быстрого введения.

    Также рекомендую посмотреть общие лекции по веб-разработке от техносферы, чтобы иметь представление об основах dns, http и БД. Там есть примеры на django, но, учитывая, что вам знаком python, это не должно вызвать трудностей.

    Что касается php, то большинство книг по нему описывают сам язык и не описывают, как создавать реальное приложение. «Learning PHP, MySQL, and JavaScript» подойдет для старта, но нужно быть готовым к тому, что так, как показано в книге, сейчас никто не пишет - это код десятилетней давности, а приведен он лишь для иллюстрации базового синтаксиса. Современный php предполагает разработку на фреймворках - их изучением и надо заниматься после освоения языка.

    P.S. Похожий вопрос на тостере без привязки к конкретному языку: Существует ли книга для новичка, в которой показывают разработку реального проекта?
    Ответ написан
    Комментировать
  • Как в SimpleXMLReader получить атрибут родительского элемента N уровня, зная его дочерний элемент?

    @SilverSlice
    Расширение XMLReader, которое используется в SimpleXMLReader, читает документ в потоке, т.е. последовательно, без построения дерева DOM. Поэтому вы не сможете обратиться к родительским элементам. Вам нужно при чтении запомнить в переменной атрибут (артикул) нужного элемента и потом подставить его в результирующий массив.

    Должно получиться примерно так:
    $reader = new XMLReader();
    $reader->open('file.xml');
    
    $attributes = array();
    $i = 0;
    while ($reader->read()) {
        if ($reader->nodeType == XMLReader::ELEMENT && $reader->localName == 'Product') {
            $articul = $reader->getAttribute('Articul');
    
            while ($reader->read()) {
                if ($reader->nodeType == XMLReader::ELEMENT && $reader->localName == 'Property') {
                    $attributes[$i]['id'] = $reader->getAttribute('ID');
                    $attributes[$i]['name'] = $reader->getAttribute('Name');
                    $attributes[$i]['sort_order'] = $reader->getAttribute('Sort');
                    $attributes[$i]['articul'] =  $articul;
                    $i++;
                }
                if ($reader->nodeType == XMLReader::END_ELEMENT && $reader->localName == 'Product') {
                    break;
                }
            }
        }
    }
    Ответ написан
    Комментировать
  • Как работает Web-сервер?

    @SilverSlice
    • Котеров «PHP5 в подлиннике». Первые три главы посвящены основам tcp, dns, http. Детально разбирается написание cgi-сценария на c.
    • Лекции от Техносферы mail.ru «Разработка интернет-приложений».
    Ответ написан
    Комментировать
  • Как сгруппировать строки c картинками в excel средствами PHP?

    @SilverSlice
    Xlsx-файл - это zip-архив, распаковываете его средствами php и находите файл xl/drawings/drawing1.xml. В нем содержится информация о картинках на листе.

    PHPExcel все картинки помещает в элементы oneCellAnchor (перемещать, но не изменять размеры), вам нужно поменять их на twoCellAnchor (перемещать и изменять объект вместе с ячейками). Обращайтесь к документации по Open Office XML за подробностями.

    UPD. Реализовал этот алгоритм в библиотеке. Попробуйте, на моих тестовых данных все работает.
    Ответ написан
    Комментировать
  • Как настроить сервер на Apache для отправки писем с помощью PHP mail()?

    @SilverSlice
    Как минимум, у вас некорректно настроен hostname, поэтому сервер не принимает ваше сообщение.

    Проще всего будет поставить PHPMailer и отправлять письма через smtp того же рамблера.

    Если же вы хотите все-таки свой почтовый сервер, то нужно прописать hostname, а также настроить PTR и SPF записи. Вот вам ссылки в помощь:
    https://www.linode.com/docs/getting-started#settin...
    geektimes.ru/post/59417
    habrahabr.ru/post/101628

    После этого можете проверить отправку почты с помощью сервиса mail-tester.com, отправив письмо из консоли:
    echo "This is a test." | mail -s Testing someone@somedomain.com
    Ответ написан
    Комментировать
  • Есть ли программа для синхронизации c FTP локальной папки?

    @SilverSlice
    • Для отслеживания изменений в локальных файлах используйте git и bitbucket.
    • Для загрузки на ftp только измененных файлов используйте PHPloy. Это библиотека на php, которая сверяет версию локальных файлов и удаленных файлов и загружает по ftp только нужные.

    Ваш рабочий процесс будет выглядеть так:
    1. На компьютере 1 вносите изменения в локальные файлы, фиксируете изменения (git commit) и отправляете на bitbucket (git push). Запускаете PHPloy для загрузки ваших изменений на ftp-сервер (phploy).
    2. На компьютере 2 получаете изменения из bitbucket (git pull) и дальше работаете как в пункте 1.
    3. Такая схема исключает возможность ручной правки файлов на сервере. Все изменения нужно вносить только через git.

    Преимущества такой схемы:
    • Всегда имеете последнюю версию кода в центральном репозитории на bitbucket. Туда не попадут вирусы в случае взлома ftp или cms.
    • Заливаете все изменения на ftp одной командой без необходимости помнить, какие файлы вы меняли.
    • Легко можете откатить код к предыдущей версии на ftp простым запуском phploy --rollback.
    Ответ написан
    6 комментариев
  • Как правильно фильтровать входящие данные?

    @SilverSlice
    Для начала предлагаю уточнить значение слова фильтровать, выделив следующие варианты обработки пользовательских данных.
    1. Валидация, т.е. проверка соответствия введенных пользователем данных вашей бизнес-логики.
    2. Фильтрация, т.е. преобразование входных данных определенным образом. Например, вы можете обрезать начальные пробелы в строке или вырезать из неё html-тэги.
    3. Форматирование данных для корректной вставки в БД, вывода в HTML и т.д.

    Для выполнения первых двух пунктов в php есть расширение Filter, которое занимается проверкой и очисткой входных данных.

    Третий пункт говорит, что если данные, полученные от пользователя, куда-либо подставляются, то они должны быть корректно отформатированы. Причем делать это нужно непосредственно в момент подстановки (записи в БД или вывода в html).

    При выводе данных в html (если вы явно не допускаете вывод html-тегов) все специальные символы (кавычки, знаки больше и меньше, амперсанд) должны быть преобразованы в HTML-сущности. Этим как раз и занимается функция htmlspecialchars. Htmlentities преобразует не только эти символы, но и многие другие (точный список можно получить функцией get_html_translation_table). Если вы используете на сайте utf-8, то она вам вообще не нужна.

    Теперь о том, на что стоит обратить внимание при использовании htmlspecialchars:
    • В третьем параметре нужно указать кодировку, которую вы используете на сайте.
    • Во втором параметре стоит указать флаг ENT_QUOTES, чтобы преобразовывались как двойные, так и одинарные кавычки. Потому как атрибуты могут быть записаны с использованием обеих (href="" и href=''). В html всегда стоит использовать кавычки при записи атрибутов (не пишите src=image1.jpg).
    • Во втором параметре вы также можете указать флаг ENT_SUBSTITUTE (для php >= 5.4). В случае, если ваша строка будет содержать некорректно закодированные символы, они будут заменены на символ юникода. Без указанного флага вы получите пустую строку (подробности).

    Итоговый вариант использования htmlspecialchars:
    htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');


    Советую также посмотреть документацию к библиотеке Zend\Escaper, которая содержит примеры корректного и некорректного форматирования данных при выводе в различные части html-документа.
    Ответ написан
    Комментировать
  • Продвинутая литература по тестированию?

    @SilverSlice
    Real-World Solutions for Developing High-Quality PHP Frameworks and Applications. Один из авторов - создатель PHPUnit. Книга местами устарела, но кое-что, возможно, почерпнёте.
    Ответ написан
    Комментировать
  • Как менее ресурсоемко обработать 2 масива?

    @SilverSlice
    • Если в массивах нет повторяющихся значений и значения имеют лишь тип int или string, то можно сделать array_flip второго массива и в цикле по первому проверять наличие ключей во втором через isset.
    • Если в массивах нет повторяющихся значений, а предыдущий вариант не подошел, можно взять вашу реализацию, убрав из неё in_array.
    • Если в массивах возможны повторяющиеся значения, в предыдущем варианте заменить array_search на array_keys.

    Если передумаете и захотите кода и тестов - добро пожаловать.
    Ответ написан
    Комментировать
  • Как распарсить doc Обработать php и сохранить обратно?

    @SilverSlice
    Если нужно всего лишь заменить пару строк в документе, то есть простое решение. Сохраняйте его в формате docx - это zip-архив, в котором есть файл document.xml, содержащий текст документа. Простой заменой можете поменять нужные слова.

    Вот вам готовая библиотека для этих целей: https://github.com/silverslice/docx-template
    Ответ написан
    1 комментарий
  • На какое время можно кешировать результаты определения города по IP?

    @SilverSlice
    Рассчитывайте время, исходя из интервала обновления базы Sypexgeo, который зависит от используемой редакции.
    Ответ написан
    Комментировать
  • Что учить перед тем как окунуться в PHP?

    @SilverSlice
    Начиная с алгоритмов, вы рискуете задушить свой интерес к программированию. Возьмите что попроще для начала. Почему бы вам не присмотреться к javascript? Не совсем backend, но его знание будет очень полезным для веб-разработчика.

    Есть отличные общедоступные учебники с упражнениями:
    - learn.javascript.ru
    - Выразительный Javascript

    Познакомитесь с основами программирования, решите, нравится ли вам этим заниматься, а потом можете браться за более серьезное изучение. Чтобы уверенно разбираться в современном php, нужно будет освоить как минимум ООП и шаблоны проектирования. Ну а если дальше ваш интерес будет сохраняться, то наши советы вам уже не понадобятся - сами доберетесь до алгоритмов, Фаулера, DDD и прочего.
    Ответ написан
    Комментировать
  • Почему не работает trim?

    @SilverSlice
    Главный спутник программиста - отладка. Если две строки неравны, значит нужно посмотреть, чем именно они отличаются. Т.е. вывести код каждого символа и сравнить. Сделать это можно, например, так:

    for ($i = 0; $i < strlen($str1); $i++) {
        echo ord($str1[$i]) . ' ';
    }

    Когда вы сравните строки, то увидете, что в $str2 у вас больше символов, значение которых можно найти в любой таблице ASCII. Тогда подтвердится ваше предположение о символах конца строк (которое, к слову, подробно описано в документации к функции, которую вы используете).

    Таким образом вы поймете, что по ошибке применили trim совсем не к той переменной.
    Ответ написан
    1 комментарий
  • Как узнать источник перехода(HTTP_REFERER) с https на http?

    @SilverSlice
    Странные у вас тесты. Зайдите на страницу другого поиска и потестируйте в хроме и фаерфоксе. Первый передает только домен, т.к. на странице стоит <meta name="referrer" content="origin">, второй ничего не передает, т.к. поддержка meta referrer пока есть только в 36 бэте.

    Что касается google и яндекс, они делают редирект через http с помощью meta refresh. Так что ответ - никак, если только не установлен meta referrer тэг.
    Ответ написан
    Комментировать
  • Как заменить словосочетание везде, кроме тегов h1-h6 и a?

    @SilverSlice
    $html = '<h1>Man Gnoy artrit in the text</h1>
    Some text about artrit.
    <p>There are many types of side. Gnoy artrit may be other side and gnoy artrit once more.</p>
    Non gnoy artrit
    <a href="#">Anoter text gnoy artrit side.</a>
    Some ending text.
    Non gnoy artrit
    <h5>Anoter text of gnoy artrit side.</h5>
    Some ending text.';
    
    $dom = new DomDocument();
    $dom->loadHTML($html);
    
    $keyword = 'gnoy artrit';
    $xpath = new DomXPath($dom);
    $nodes = $xpath->query("
        //text()[contains(
            translate(., 'ABCDEFGHJIKLMNOPQRSTUVWXYZ', 'abcdefghjiklmnopqrstuvwxyz'),
            '$keyword')
            and not(ancestor::h1)
            and not(ancestor::h2)
            and not(ancestor::h3)
            and not(ancestor::h4)
            and not(ancestor::h5)
            and not(ancestor::h6)
            and not(ancestor::a)]
    ");
    foreach ($nodes as $node) {
        $replace = function($node, $keyword) use (&$replace) {
            $startPos = stripos($node->textContent, $keyword);
            if ($startPos === false) {
                return;
            }
    
            $keynode = $node->splitText($startPos);
            $restnode = $keynode->splitText(strlen($keyword));
            $replacement = new DOMElement('strong', $keynode->textContent);
            $node->parentNode->replaceChild($replacement, $keynode);
            $replace($restnode, $keyword);
        };
        $replace($node, $keyword);
    }
    
    echo $html;
    echo '<hr>';
    echo $dom->saveHTML();
    Ответ написан
  • Перебор строк в MYSQL-ответе (mysql_query / mysql_fetch_assoc), как сделать кошерно?

    @SilverSlice
    Вы же сами видите, что удобство работы с "голым" расширением mysql стремится к 0. Вам действительно нравится писать бесконечные mysql_real_escape_string и бегать циклами по результату запроса?

    Если нет возможности внедрять PDO или другие обертки в свой legacy-код, следует написать свою, которую уже сейчас можно будет использовать. А нужно от неё совсем немного:

    1. Удобство получения данных.
    Вместо
    $result = mysql_query($query);
    if ($result) {
        $items = array();
        while ($row = mysql_fetch_assoc($result)) {
            $items[] = $row;
        } 
    }

    мне хочется использовать
    $items = db_get_all($query);

    2. Удобство подстановки данных в запрос.
    Вместо
    mysql_query("SELECT * FROM table WHERE field = '" . mysql_real_escape_string($one) . "' OR field2 = '" . mysql_real_escape_string($two) . "'");

    мне хочется использовать
    db_query("SELECT * FROM table WHERE field = ? OR field2 = ?", $one, $two);


    Вот нашел свой старый wrapper, можете написать подобный и сильно облегчить себе работу.
    Ответ написан
  • Как сделать замер скорости работы скрипта?

    @SilverSlice
    А что у вас в скрипте? Если есть обращение к БД, то скорее всего при повторных вызовах скрипта на результат влияет кэш СУБД.
    Ответ написан
    Комментировать