Ответы пользователя по тегу PHP
  • Как не завершать сессию командной строки при использовании shell_exec()?

    @MadridianFox
    Web-программист, многостаночник
    Никак.
    Каждый вызов shell_exec порождает новый процесс командного интерпретатора (bash или cmd), который наследует переменные окружения от текущего php процесса.
    Текущая дирректория это состояние командного интерпретатора, которое теряется между вызовами shell_exec.

    В зависимости от решаемой задачи, вам необходимо либо запускать отдельно процесс cmd и передавать в него команды, либо запоминать текущее состояние и добавлять в каждый вызов shell_exec установку этого состояния, наприме банально вставлять перед каждой командой cd вот так:
    $cwd = "/path/to/dir";
    shell_exec("cd {$cwd}; ls");
    shell_exec("cd {$cwd}; chmod +x banana.sh");
    Ответ написан
    1 комментарий
  • Как сделать редирект на вывод из echo?

    @MadridianFox
    Web-программист, многостаночник
    Используйте заголовок редиректа
    header("Location: $link");
    Ответ написан
  • Насколько защищена представленная конструкция php?

    @MadridianFox
    Web-программист, многостаночник
    Уязвимость - это когда злоумышленник использует такие варианты параметров, обработку которых разработчик не предусмотрел.
    Варианты обработки параметров - это не только когда мы явно сравниваем переменную с чем-то. Например печально известная функция printf() в языке Си принимает шаблон и значения, которые в него надо ставить, если шаблон может ввести пользователь, то он может подобрать такой шаблон, который выдаст больше чем планировал разработчик.
    printf - потенциально уязвимая функция.
    К потенциально уязвимым функциям можно отнести интерпретирующие функции. Например запрос к БД. Например через одну лишь функцию mysql_query() можно в теории сделать с БД что угодно.
    Это "что угодно" ограничивается тем какой запрос передаётся в функцию. Однако если запрос хоть как-то зависит от того что ввёл пользователь, то разработчику надо предусмотреть любые варианты ввода пользователя так, чтобы запрос продолжал делать то что нужно разработчику, а не пользователю.
    Но не только лишь божественные интерпретирующие функции кроют в себе опасность. Например сохранение некоторой строки в БД и последующий вывод этой строки на страницу тоже может быть опасным, хотя при записи в БД эта строка безопасна. Я говорю о подстановке js кода в страницу, которая будет показана другому человеку.
    Т.е. варианты использования введёного пользователем параметра не ограничиваются той функцией которая непосредственно обрабатывает введённый параметр, но и накапливаются дальше за всё время использования данных, которые когда-то ввёл пользователь.

    К чему я это всё?
    К тому, что для того чтобысказать уязвим ли этот код, нужно оценить как на него повлияют разные варианты введённого логина и пароля или других параметров, которые возможно есть в этом скрипте.
    Я не вижу в этом коде божественных функций, не вижу никакого другого использования введённых параметров кроме их сравнения с литералом. На основании этого могу сказать, что код вполне надёжен.
    Конечно, всегда есть опасность того, что, допустим по историческим причинам оператор === для строк имеет особое поведение, когда в строке есть символ 0xFFAA.
    Ответ написан
    2 комментария
  • Как средствами php запустить выполнение linux-команды в фоновом режиме?

    @MadridianFox
    Web-программист, многостаночник
    nohup - это команда bash, которая просто указывает самому bash'у что фоновому процессу не надо отправлять сигнал HUP при завершении работы.
    & это тоже фишка bash, позволяющая перевести процесс в фон

    Проблема в том что php это вам не bash и он наверное сам отслеживает состояние запущенного им процесса.

    Попробуйте использовать setsid.
    В отличие от nohup это полноценная программа, которая запускает указанную в качестве аргумента программу в отдельной сессии. Как только целевая программа запущена setsid завершает работу. Это должно "отпустить" php почти моментально.
    Ответ написан
  • Отправка почты с формы?

    @MadridianFox
    Web-программист, многостаночник
    Важно не то, где код находится, а то, в какой последовательности данные отправляются/заносятся.
    Если это на одной странице, то старайтесь сделать это одной большой формой, либо собирайте данные с форм и отправляйте потом на сервер сразу все данные.

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

    @MadridianFox
    Web-программист, многостаночник
    Когда у вас есть очередь сообщений, вам нужны программы, которые запускаются один раз и в цикле читают и обрабатывают сообщения из очереди. Ну и супервизор над ними, который будет их поднимать если они падают.

    Т.е. ваши сервисы не должны запускаться по крону, а должны постоянно работать.
    Ответ написан
    Комментировать
  • Как сделать json недоступным для просмотра в браузере?

    @MadridianFox
    Web-программист, многостаночник
    Можно проверять чтобы был заголовок HTTP_X_REQUESTED_WITH в котором указано что запрос имеет тип xmlhttprequest, т.е. ajax.

    А вообще, кому оно надо - открывать в браузере url'ы из кода? Если кто-то прям очень захочет - он сам сформирует такой запрос и всё-равно получит данные. Априори нельзя защитить контент, который вы хотите отдать в браузер.
    Ответ написан
    2 комментария
  • Является ли данный код защищенным от SQL инъекций?

    @MadridianFox
    Web-программист, многостаночник
    От инъекции как таковой код защищён. По крайней мере в лоб передать кусок запроса уже не получится.
    Однако надо проверять что пользователь передаёт название существующего поля, чтобы код не падал.
    А ещё надо следить чтобы сервер автоматически не превращал параметры запроса в переменные, чтобы пользователь, случайно или умышленно, не затёр вам $fields собственным массивом.
    Хотя мне кажется это первое чему учат, когда говорят про безопасность в PHP)
    Ответ написан
    3 комментария
  • Почему не увеличивается значение в базе данных?

    @MadridianFox
    Web-программист, многостаночник
    У вас запросы неправильные.
    Должно быть
    UPDATE golosa SET var1 = '$row[1]' where id = 1

    А вообще лучше изменить логику работы всего скрипта.
    Вы можете в форме знfчением радиокнопок делать не название картинки, а их id.
    Тогда можно будет выполнить запрос вида:
    UPDATE golosa SET var1 = var1 + 1 where id = ?
    и с помощью prepared statements подставить id картинки в запрос.
    Ответ написан
  • Как подружить Windows 10 + Docker + PhpStorm + Xdebug?

    @MadridianFox
    Web-программист, многостаночник
    Я для себя определил универсальный подход для отладки в любом сетевом окружении.
    В простейшем случае, когда разработчик один, а сервер за NAT, надо на сервер прокинуть порт через ssh.
    ssh user@host -R 9000 localhost:9000
    При этом в php.ini xdebug надо настроить чтобы он коннектился на localhost:9000.

    Когда разработчиков много, я использую модифицированный dbgp прокси.
    https://github.com/MadridianFox/php-xdebug-proxy
    Если он стоит на том же сервере что и php, настройки xdebug те же. Прокси слушает 9000 порт. Каждый разработчик выбирает себе уникальный порт и прокидывает его по ssh на сервер. Так же надо обратно прокинуть 9001 порт чтобы зарегистрировать свой idekey в прокси.
    ssh user@host -R 9002 localhost:9002 -L 9001 localhost:9001

    И самое главное - при регистрации своего idekey через шторм в поле idekey надо написать myidekey:9002
    В этом же окне порт прокси - 9001, хост прокси - localhost.

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

    В браузере, не важно, используете вы расширение или прописываете XDEBUG_SESSION_START, надо указать myidekey без порта!

    В случае с докером вы можете либо добавить ssh сервер в контейнер с самим php, либо поднять дополнительный ssh контейнер. При единоличной разработке этого достаточно. Просто в зависимости от размещения ssh прописываете разные хосты в xdebug. Прокидывает туда порт.

    Если разработчиков больше одного - выделяете контейнер с ssh + dbgp прокси и каждый разработчик прокидывает туда свой порт.
    Ответ написан
    Комментировать
  • Как сделать автокоплит для объектов в цикле foreach?

    @MadridianFox
    Web-программист, многостаночник
    phpdoc для метода getRoutes напишите и укажите в нем тип возвращаемого значения.

    Или можно /** @var $route Type */ в теле цикла указать.
    Ответ написан
    Комментировать
  • Организация index.php в проекте?

    @MadridianFox
    Web-программист, многостаночник
    Да, вы можете проверить существование класса. А если его нет то что? Будете использовать другой класс? Наверное нет, потому что в 99% случаев такого в нормальной ситуации не бывает. Нет класса - фатал эррор. Всё-равно продолжать бессмысленно. Ошибка сама запишется в лог, остаётся только настроить веб-сервер чтобы на 500 ошибку выдавал станицу с вашим стилем.
    Всё остальное решается использованием системы внедрения зависимостей.
    Ответ написан
  • Как записать html+php шаблон в переменную?

    @MadridianFox
    Web-программист, многостаночник
    Почитайте про функции ob_start(), ob_get_clean() и подобные. Они захватывают вывод в буфер, и этот буфер можно получить в виде строки.
    Ответ написан
    Комментировать
  • Есть средство которое позволяет измерить скорость скрипта php на разных участках кода?

    @MadridianFox
    Web-программист, многостаночник
    Проще всего использовать расширение xdebug. Оно помимо отладки позволяет профилировать код. Работает это так: добавляете в адресной строке специальный параметр (лучше использовать специальное расширение для браузера) и при отработке вашего php скрипта дополнительно будет создан файл, куда будет записано какая функция сколько раз распускалась и сколько времени выполнялась.
    Этот файл можно открыть специальной программой, которая позволяет сортировать функции по времени выполнения, а так же смотреть на дерево вызовов.
    Ответ написан
    Комментировать
  • Как реализовать комментарии на сайте на ООП с помощью MVC?

    @MadridianFox
    Web-программист, многостаночник
    Традиционно комментарии на сайтах относятся к чему-то. Например к статье, новости, файлу и т.д.
    Это значит, что комментарии обычно находятся на странице с комментируемым объектом. Т.е. комментарии это не отдельный раздел и даже не самостоятельная страница, а лишь часть страницы.

    С другой стороны MVC - это даже не шаблон проектирования, а нечто большее - это способ организации структуры программы. Обычно ВСЕЙ программы.

    Таким образом, сделать по MVC только часть сайта... да что там сайта, часть страницы! не очень то возможно, т.к. традиционно одна страница - это один контроллер (Page Controller, который часто выражен методом определённого класса, тоже называемого контроллером).

    Вы всё ещё можете создать модель комментариев. Даже можете красиво отделить представление комментариев. Но вот отдельный контроллер комментариев... это вряд-ли.

    Но на самом деле всё зависит от используемого фреймворка и от технологий, с помощью которых вы эти комментарии будете делать.
    Вдруг сайт написан на Symfony, а комментарии вы хотите подгружать по ajax? Тогда конечно и контроллер отдельный можно чисто для комментариев сделать.
    Ответ написан
    Комментировать
  • Взаимодействие контроллера и модели?

    @MadridianFox
    Web-программист, многостаночник
    1) Вы пишете что модель сама берёт данные из post. Зачем тогда вам контроллер? Это плохая модель, она зависит от способа передачи данных . Контроллер должен получать данные и передавать их модели. А методы должны называться в соответствии с тем что они делают. Могут называться и одинаково, тут вопрос не к названию, а к содержимому.
    2) то же самое. Модель должна вернуть данные, а уже контроллер дальше положит их куда надо.
    3) подумайте сколько раз за один http-запрос будет создан лишний объект. Если это количество само по себе велико или зависит от обрабатываемых данных (например по одному лишнему объекту на выводимый на странице комментарий пользователя) то это плохо. Если один раз, то зависит от способа создания объекта. Если в конструкторе выполняются ресурсоёмкие операции, то... Это само по себе плохо. Конструктор не должен содержать кода (с некоторыми допущениями)
    4) в третий раз повторяю - модель должна вернуть значение. Прервать выполнение программы она может в одном случае - возникла ошибка, такая что дальше работать бессмысленно. Для этого есть исключения. Контроллер должен поймать исключении и завершить выполнение, а лучше показать сообщение - "ой, возникла ошибка".
    Во всех других случаях модель делает return, управление передаётся контроллеру и уже он, если необходимо делает die().
    Хотя само по себе использование die() чаще всего является костылём.
    Ответ написан
  • Где правильно вставить вызов mysql?

    @MadridianFox
    Web-программист, многостаночник
    В php нет таймеров. И в mysql тоже. И триггер тут не поможет.
    Как уже написал Дмитрий Кузнецов необходимо делать отдельный php файл с кодом, который будет выполнять запрос на удаление и настраивать крон, чтобы этот файл запускался раз в несколько секунд.
    Ответ написан
  • Объясните доступным языком что такое PDO и почему лучше использовать его?

    @MadridianFox
    Web-программист, многостаночник
    MуSQL уже отходит на задний план

    Не СУБД MySQL, а расширение php которое даёт функции mysql_*** считается устаревшим.
    PDO и mysqli это такие же расширения, которые дают вам возможность соединяться с базой и выполнять запросы. Они предоставляют более удобное api.
    Ответ написан
  • Как обходиться со свойствами и значениями по умолчанию внутри класса?

    @MadridianFox
    Web-программист, многостаночник
    Тут вопрос глубже - а зачем вам геттеры и сеттеры которые ничего не делают?
    Вот у вас есть поле. Вы делаете его протектед, и тем самым говорите внешнему миру - это моё поле, вам о нём знать не надо, оно нужно мне для моей внутренней работы. Ок.
    Если вам надо дать возможность снаружи писать и читать это поле, то... вам не надо делать его протектед.

    Вот, если бы вы делали какие-то преобразования, то тут ещё может быть... Вот представьте, что у вас в объекте есть поле, которое хранит дату. Вы делаете методы setDate(string $date) и getDate(): string, но в поле записываете не строку, а объект DateTime. Вот тогда всё логично, и вопроса - пользоваться ли геттером и сеттером внутри класса не возникает. Хотите работать напрямую с DateTime - работаете с полем. Хотите со строкой - работаете с геттером и сеттером.

    Другой пример - вы делаете только геттер или только сеттер. С помощью только геттера вы делаете ваше поле read only. оно доступно снаружи, но снаружи его никто не изменит. Внутри класса использовать такой геттер не имеет смысла.
    Ответ написан
    4 комментария