Показаны сообщения с ярлыком php. Показать все сообщения
Показаны сообщения с ярлыком php. Показать все сообщения

07 октября 2018

Пересобрал пакеты PHP 7.1.20 и 7.2.9 для Debian Stretch

По-умолчанию в Debian Stretch поставляется PHP версии 7.0.30, но свежие версии Laravel требуют как минимум PHP версии 7.1.3. Чтобы решить эту проблему я пересобрал пакеты PHP 7.1.20 и 7.2.9 для Debian Stretch (только amd64). Никаких модицикаций делать не пришлось, только добавил суффикс "~stretch1" к версии пакета.

Найти их можно в секции backports моего репозитария или скачать напрямую (7.1.20 и 7.2.9). Все три версии можно установить одновременно, но для mod_php нужно включать нужную версию явно.

Вы можете следить за обновлениями блога с помощью Atom/RSS и Telegram.

03 мая 2016

Сломался owncloud 9.0.1 после обновления php до 7.0.6

После обновления PHP с 7.0.5 до 7.0.6 сломался owncloud 9.0.1. При попытке залогиниться предлагает логиниться еще раз и так по кругу. Никаких ошибок или предупреждений при этом не выдает.

В логе data/owncloud.log ничего нет. Чтобы выяснить что происходит при логине включил отладку в config/config.php

<?php
$CONFIG = array (
...
  'debug' => true,
  'loglevel' => 0,
);

Но ничего интересного в лог не записалось. Все заработало после отката версии PHP до 7.0.5.

На форуме owncloud нашлось обсуждение аналогичной проблемы и ссылка на пул реквест, который решает проблему. Патч для owncloud который установлен официальных пакетов выглядит так:

--- lib/private/appframework/http/request.php.orig      2016-05-03 13:19:36.893158727 +0300
+++ lib/private/appframework/http/request.php   2016-05-03 13:20:13.750028337 +0300
@@ -264,6 +264,9 @@
         * @return bool
         */
        public function __isset($name) {
+               if (in_array($name, $this->allowedKeys, true)) {
+                       return true;
+               }
                return isset($this->items['parameters'][$name]);
        }

Применить патч можно так:

$ cd /var/www/owncloud/
$ sudo patch -p0 < /tmp/owncloud-9.0.1-php-7.0.6-login.patch

Вы можете следить за обновлениями блога с помощью Atom/RSS и Telegram.

10 сентября 2015

Warning: imagecreatefrompng(): bad type specifier while parsing parameters

Сегодня выловил ошибку после обновления PHP на Squeeze-LTS инсталляции. Была версия 5.3.3.1-7+squeeze26, а обновилось до 5.3.3.1-7+squeeze27.

Возможно проблема появилась после этого фикса:

 * CVE-2015-3411 + CVE-2015-3412
  Fixed bug #69353 (Missing null byte checks for paths in various
  PHP extensions)

Пока ошибка проявилась только при использовании функции imagecreatefrompng(), но возможно затронуто еще что-то.

Чтобы решить проблему достаточно сделать откат к старой версии. Я уже отписался в рассылку debian-lts - посмотрю, что там скажут.

Вы можете следить за обновлениями блога с помощью Atom/RSS и Telegram.

16 мая 2015

Please create a GitHub OAuth token to go over the API rate limit

В процессе установки обновлений есть время, когда просто сидишь и созерцаешь процесс. Чтобы немного развлечься решил попробовать запустить magento на php7. По ссылке обещают производительность даже выше, чем у HipHop.

Magento 1.9 не завелась, но разбираться в причине лень, поэтому решил попробовать magento 2 beta. В процессе установки composer выдал:

  - Installing sjparkinson/static-review (4.1.1)
    Downloading: Connecting...
Could not fetch https://api.github.com/repos/sjparkinson/static-review/zipball/493c3410cf146a12fca84209bad126c494e125f0, please create a GitHub OAuth token to go over the API rate limit
Head to https://github.com/settings/tokens/new?scopes=repo&description=Composer+on+php7+2015-05-16+1102
to retrieve a token. It will be stored in "/home/admin/.composer/auth.json" for future use by Composer.

Похоже я слишком часто последнее время стал пользоваться composer.

Вы можете следить за обновлениями блога с помощью Atom/RSS и Telegram.

16 апреля 2015

ldap_bind(): Unable to bind to server: Protocol error

Делаю страничку для показа информации о сотрудниках из OpenLDAP. Столкнулся с тем, что простейший код не может подключиться к LDAP серверу, хотя binddn и bindpw верные - это было проверено через ldapsearch. Как оказалось по-умолчанию php-ldap использует LDAPv2, а наш LDAP сервер настроен на LDAPv3. Чтобы решить эту проблему достаточно добавить в код:

ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);

Вы можете следить за обновлениями блога с помощью Atom/RSS и Telegram.

24 февраля 2015

Пакетирование php pecl расширений в Debian

Пакетирую php pecl расширение yaml. Нагуглил хороший гайд как быстро и расово верно пакетировать эти вещи в Debian.

Вы можете следить за обновлениями блога с помощью Atom/RSS и Telegram.

23 февраля 2015

Будьте внимательны при апгрейде Nginx + PHP-fpm в Debian Jessie

При обновлении хоста с Debian Jessie столкнулся с полностью нерабочими PHP сайтами после завершения апгрейда сервера. На любой запрос php скрипта веб-сервер просто отвечает HTTP 200 и отдает пустую страницу. Никаких ошибок в логе Nginx не было.

Сайты содержали следующий кусок конфига:

location ~ \.php$ {

  # skipped lines

  fastcgi_pass unix:/var/run/php5-fpm.sock;
  fastcgi_index index.php;
  include fastcgi_params;
}

В процессе дебага выяснилось, что из файла /etc/nginx/fastcgi_params выкинули объявление параметра SCRIPT_FILENAME и из-за этого интерпретатору срывает крышу. Случилось это в районе версии 1.6.1-2:

  * debian/conf/fastcgi_params:
    + Sync with upstream and remove `SCRIPT_FILENAME` parameter.
      This change might break fastcgi sites. (Closes: #718639)
  + debian/conf/fastcgi.conf:
    + Ship upstream file.

Теперь в Nginx включен пример конфигурации для PHP-fpm (/etc/nginx/snippets/fastcgi-php.conf)

# regex to split $uri to $fastcgi_script_name and $fastcgi_path
fastcgi_split_path_info ^(.+\.php)(/.+)$;

# Check that the PHP script exists before passing it
try_files $fastcgi_script_name =404;

# Bypass the fact that try_files resets $fastcgi_path_info
# see: http://trac.nginx.org/nginx/ticket/321
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;

fastcgi_index index.php;
include fastcgi.conf;

P.S. Особая благодарность создателям socat - он мой новый лучший друг в вопросах отладки. Достаточно запустить

socat -v UNIX-LISTEN:/tmp/php5-debug.sock UNIX-CONNECT:/var/run/php5-fpm.sock

и перенастроить Nginx на подключение к /tmp/php5-debug.sock, как становится виден процесс общения Nginx и PHP-fpm, а соответственно и суть проблемы.

Вы можете следить за обновлениями блога с помощью Atom/RSS и Telegram.

22 января 2015

Что будет если в нескольких вкладках браузера запустить один и тот же скрипт?

Наткнулся на интересный момент, который связан с работой браузеров. Имеется PHP скрипт у которого есть защита от одновременного запуска нескольких копий через flock()

<?php
$fp = fopen($_SERVER['SCRIPT_FILENAME'], 'r');

if (flock($fp, LOCK_EX | LOCK_NB)) {
    echo 'Job started' . PHP_EOL;
    sleep(10);
    flock($fp, LOCK_UN);
} else {
    echo 'Another job already running' . PHP_EOL;
}

fclose($fp);
?> 

Такой код обеспечивает надежную блокировку от одновременного запуска нескольких копий задания на уровне процесса. Но при тестировании оказалось, что если этот скрипт запустить в нескольких вкладках одного браузера, то вместо быстрого завершения с выводом 'Another job already running' вкладки последовательно срабатывали, выводя 'Job started'. Но этого быть не должно, ведь используется неблокирующий вызов flock()!

Для проверки запустил несколько запросов, через wget

$ for i in $(seq 1 5); do wget -q -O- http://localhost/flock.php & done
[1] 30876
[2] 30877
[3] 30878
[4] 30879
[5] 30880
$ Another job already running
Another job already running
Another job already running
Another job already running
Job started

Сейчас все верно - сначала в фоне запустился первый скрипт, получил блокировку и уснул, имитируя бурную деятельность. Четыре остальных запуска завершились сразу, не получив блокировку.

Я не знаю точно, почему так происходит, но возможно дело в кеше браузера. Когда URL запрашивается в первый раз он помечается в кеше как pending, пока не будет ответа от сервера. Последующие запросы того же URL в других вкладках натыкаются на незавершенную операцию и ожидают - ведь возможно удастся выдать результат, используя кеш. Когда отрабатывает первый запрос, браузер видит ответ сервера, запрещающий кеширование результата и запускает второй запрос. Таким образом все запросы выполняются последовательно, успешно получая блокировку. Завтра нужно будет проверить, действительно ли только один запрос выполняется сервером одновременно.

Вы можете следить за обновлениями блога с помощью Atom/RSS и Telegram.

13 октября 2014

PHP Fatal error: Call to undefined function hash_equals()

Довелось разбираться почему не работает плагин Mailchimp для WordPress. Анализ лога показал, что плагин использует функцию hash_equals(), которая появилась только в php 5.6.0. Обновлять PHP до последней версии - не вариант. Немного поиска и нашлась аналогичная реализация hash_equals() на PHP.

Можно либо вставить код функции в нужный файл, либо подключить через require_once().

Вы можете следить за обновлениями блога с помощью Atom/RSS и Telegram.

14 марта 2014

Nginx: запаролить доступ к директории с PHP скриптами

Очень удивился когда Nginx дал выполнить скрипт из запароленной директории. При этом на саму директорию пароль спрашивает.

Этот ответ прояснил ситуацию. Полное описание логики блока location.

Вы можете следить за обновлениями блога с помощью Atom/RSS и Telegram.

13 февраля 2014

Настройка PHP 5.3 для работы в FastCGI режиме в Debian Squeeze

Процесс установки описан для Debian Squeeze и в других дистрибутивах или релизах Debian процесс может незначительно отличаться. Устанавливаем необходимые пакеты

# aptitude install spawn-fcgi php5-cli php5-cgi php5-curl php5-gd php5-imap php5-mcrypt php5-mysql

Далее нужно создать скрипт инициализации FastCGI менеджера (spawn-fcgi)

# vim /etc/init.d/php5-fcgi

#! /bin/sh
### BEGIN INIT INFO
# Provides:          php5-fcgi
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: PHP FastCGI
# Description:       PHP FastCGI
### END INIT INFO

PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="PHP FastCGI"
NAME=php5-fcgi
DAEMON=/usr/bin/spawn-fcgi
FCGI_SOCKET=/var/run/php5-fcgi.sock
FCGI_USER=www-data
FCGI_MODE=0600
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
DAEMON_ARGS="-s $FCGI_SOCKET -M $FCGI_MODE -u $FCGI_USER -U $FCGI_USER -P $PIDFILE -- /usr/bin/php5-cgi"

[ -x "$DAEMON" ] || exit 0

[ -r /etc/default/$NAME ] && . /etc/default/$NAME

. /lib/init/vars.sh

. /lib/lsb/init-functions

do_start()
{
        start-stop-daemon --start --quiet --pidfile $PIDFILE --exec /usr/bin/php5-cgi --test >/dev/null \
                || return 1
        start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
                $DAEMON_ARGS >/dev/null \
                || return 2
}

do_stop()
{
        start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE
        RETVAL="$?"
        rm -f $PIDFILE $FCGI_SOCKET
        return "$RETVAL"
}


case "$1" in
  start)
        [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
        do_start
        case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
  stop)
        [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
        do_stop
        case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
  status)
       status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
       ;;
  restart|force-reload)
        log_daemon_msg "Restarting $DESC" "$NAME"
        do_stop
        case "$?" in
      0|1)
                do_start
                case "$?" in
                        0) log_end_msg 0 ;;
                        1) log_end_msg 1 ;; # Old process is still running
                        *) log_end_msg 1 ;; # Failed to start
                esac
                ;;
      *)
                # Failed to stop
                log_end_msg 1
                ;;
        esac
        ;;
  *)
        echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
        exit 3
        ;;
esac

:

Для определения параметров работы FastCGI нужно создать конфигурацию по-умолчанию

# vim /etc/default/php5-fcgi

export PHP_FCGI_CHILDREN=10
export PHP_FCGI_MAX_REQUESTS=1000

Запускаем сервис php5-fcgi и добавляем его в автозапуск

# invoke-rc.d php5-fcgi start
# update-rc.d php5-fcgi defaults

Вы можете следить за обновлениями блога с помощью Atom/RSS и Telegram.

04 декабря 2013

Особенности работы /usr/sbin/sendmail в разных MTA

Сегодня дебажили отправку почты в PHP приложении и наткнулись на интересную особенность эмуляции ключей /usr/sbin/sendmail в различных MTA.

Предыстория - рассматриваемое приложение отправляет письмо пользователю (user@example.net), делает Bcc: bcccopy@example.com (для внутренних нужд) и ставит Return-Path: sales@example.com. Если не лезть в дебри ООП и наслоения классов, то нужный код на PHP выглядит примерно так:

$email_to = 'user@example.net';
$email_subject = 'subject';
$email_body = 'email body';
$email_additional_headers = 'Bcc: bcccopy@example.com';
$email_additional_params = '-f sales@example.com';
mail($email_to, $email_subject, $email_body, $email_additional_headers, $email_additional_params);

Но при отправке письма из приложения приходило 3 одинаковых письма на user@example.net, на bcccopy@example.com и на sales@example.com, но при этом Return-Path: не выставлялся и выглядел примерно так: Return-Path: <www-data@www.example.com>

Нужное значание Return-Path может не выставляться, если почтовый сервер не считает пользователя доверенным, либо в вызове /usr/sbin/sendmail нет ключа -f. Проверить просто

# su - www-data
$ cat > /tmp/email.txt <_EOF_
Bcc: <bcccopy@example.com>
From: "Sales" <sales@example.com>
To: "User Full Name" <user@example.net>
Subject: subject

email body
_EOF_
$ cat /tmp/email.txt | /usr/sbin/sendmail -t -i -f sales@example.com

После выполнения пришли два письма - на user@example.net и на bcccopy@example.com, Return-Path: при этом выставлен корректно. Следовательно проблема лежит выше MTA и нужно дебажить PHP приложение.

Когда мне нужно проверить взаимодействие PHP скрипта и системы я пользуюсь sleep() и strace. Для этого в нужный PHP скрипт в самое начало вставляется sleep(60); после чего выполняется нужное действие. При этом у меня есть 60 секунд, чтобы посмотреть в http://www.example.com/server-status PID нужного мне запроса и подключиться к процессу через strace.

# strace -f -o /tmp/php-trace.log -s 8192 -p <PID>

По истечению 60 секунд приложение начнет выполнять вызовы системы, которые будут записаны в лог файле /tmp/php-trace.log. Поскольку я дебажу отправку почты через mail(), то меня интересует вызов execve()

$ grep execve /tmp/php-trace.log 
3253  execve("/bin/sh", ["sh", "-c", "/usr/sbin/sendmail -t -i  sales@example.com"], [/* 9 vars */] <unfinished ...>
3253  <... execve resumed> )            = 0
3254  execve("/usr/sbin/sendmail", ["/usr/sbin/sendmail", "-t", "-i", "sales@example.com"], [/* 9 vars */]) = 0
3255  execve("/usr/sbin/postdrop", ["/usr/sbin/postdrop", "-r"], [/* 2 vars */]) = 0

Вот теперь видно почему отправляется три письма вместо двух - где-то в приложении ошибка и перед sales@example.com не добавляется параметр -f. А раз sales@example.com указан без параметра, то он трактуется как еще один адрес назначения.

Но остается еще один вопрос - почему на некоторых серверах отправляется три письма, а на некоторых только два (правильный Return-Path не выставляется на любом сервере). Во всех случаях код приложения одинаковый и содержит ошибку.

На сервере, где пытались воспроизвести ошибку с отправкой трех писем вместо двух установлен WHM/cPanel и MTA там exim4. Поскольку код одинаковый, значит и функция mail() вызывается с одинаковыми параметрами, а значит и вызов /usr/sbin/sendmail должен быть одинаковый. На всякий случай сравниваю значение переменной sendmail_path в выводе phpinfo() на разных серверах - везде стоит одинаковое значение "/usr/sbin/sendmail -t -i". Но почему же тогда отличается поведение!

Смотрю дальше - на сервере, где отправляется только два письма стоит Exim4, а на остальных, где отправляется три письма, - Postfix. Сравниваю описание ключей -t и -i в man sendmail от этих MTA (взято из CentOS 6.5).

Exim4

-i        This option, which has the same effect as -oi, specifies that
          a dot on a line by itself should not terminate  an  incoming,
          non-SMTP message. I can find no documentation for this option
          in Solaris 2.4 Sendmail, but the mailx command in Solaris 2.4
          uses it. See also -ti.

-t        When  Exim is receiving a locally-generated, non-SMTP message
          on its standard input, the -t option causes the recipients of
          the message to be obtained from the To:, Cc:, and Bcc: header
          lines in the message instead of from the  command  arguments.
          The  addresses are extracted before any rewriting takes place
          and the Bcc: header line, if present, is then removed.

          If the command has any arguments, they specify  addresses  to
          which  the message is not to be delivered. That is, the argu-
          ment addresses are removed from the recipients list  obtained
          from  the  headers.  This  is  compatible with Smail 3 and in
          accordance with the documented behaviour of several  versions
          of Sendmail, as described in man pages on a number of operat-
          ing systems (e.g.  Solaris 8, IRIX 6.5, HP-UX  11).  However,
          some  versions  of  Sendmail  add argument addresses to those
          obtained from the headers, and  the  O'Reilly  Sendmail  book
          documents  it  that  way.  Exim  can  be made to add argument
          addresses instead of subtracting them by setting  the  option
          extract_addresses_remove_arguments false.

          If  there  are  any Resent- header lines in the message, Exim
          extracts recipients  from  all  Resent-To:,  Resent-Cc:,  and
          Resent-Bcc:  header lines instead of from To:, Cc:, and Bcc:.
          This is for  compatibility  with  Sendmail  and  other  MTAs.
          (Prior  to release 4.20, Exim gave an error if -t was used in
          conjunction with Resent- header lines.)

          RFC 2822 talks about different sets of Resent-  header  lines
          (for  when  a  message is resent several times). The RFC also
          specifies that they should be added at the front of the  mes-
          sage,  and  separated  by  Received:  lines. It is not at all
          clear how -t should operate in the present of multiple  sets,
          nor indeed exactly what constitutes a "set".  In practice, it
          seems that MUAs do not follow the RFC. The Resent- lines  are
          often  added  at  the  end of the header, and if a message is
          resent more than once, it is common for the original  set  of
          Resent-  headers to be renamed as X-Resent- when a new set is
          added. This removes any possible ambiguity.

Postfix

-i     When  reading  a message from standard input, don.t treat a line
       with only a . character as the end of input.

-t     Extract recipients from message headers. These are added to  any
       recipients specified on the command line.

       With Postfix versions prior to 2.1, this option requires that no
       recipient addresses are specified on the command line.

Sendmail

-i     Ignore  dots  alone on lines by themselves in incoming messages.
       This should be set if you are reading data from a file.

-t     Read message for recipients.  To:, Cc:, and Bcc: lines  will  be
       scanned  for recipient addresses.  The Bcc: line will be deleted
       before transmission.

Смысл опции -i примерно одинаков у всех MTA (хотя значение ignore у sendmail, еще нужно проверить - возможно он вовсе выкидывает строку, содержащую только символ точки). А вот после прочтения разделов про опцию -t все становится на свои места. На серверах где стоит exim4 используется отличное от sendmail и postfix поведение, когда получатели, указанные в командной строке, исключаются из итогового списка получателей письма.

Вы можете следить за обновлениями блога с помощью Atom/RSS и Telegram.

13 ноября 2013

Срочно выйти из сна - headshot.php

В фильме Inception чтобы досрочно выйти из сна, нужно было умереть. Иногда подобная необходимость бывает и на сервере, когда нужно быстро прибить все запущенные запросы, а админского доступа нет.

Этот скрипт, будучи запущенным из браузера на сервере должен сделать эту работу

$ cat headshot.php
<?php
system('PHP_PPID=`ps -p $$ -o ppid=`; PHP_NAME=`ps -p $PHP_PPID -o comm=`; pkill -u `id -un` $PHP_NAME');

Почему не просто pkill -u `id -un`? Потому что имени пользователя под которым работают скрипты на сервере, может быть запущено много чего другого, которое не стоит убивать.

Вы можете следить за обновлениями блога с помощью Atom/RSS и Telegram.

29 марта 2013

session.save_handler = eaccelerator в PHP

Если у вас в свежем eaccelerator (проверял на 0.9.6) не регистрируется хендлер в PHP сессиях, то поможет откат на версию 0.9.5.x.

$ wget --no-check-certificate https://github.com/eaccelerator/eaccelerator/archive/0.9.5.zip -O eaccelerator-0.9.5.zip
$ unzip eaccelerator-0.9.5.zip
$ cd eaccelerator-0.9.5
$ phpize
$ ./configure --enable-eaccelerator=shared --without-eaccelerator-encoder --without-eaccelerator-loader --with-eaccelerator-shared-memory --with-eaccelerator-content-caching --with-eaccelerator-sessions
$ make
$ make install

Я не в курсе почему нет сессий в новой версии - в ChangeLog ничего не видно на этот счет.

UPDATE: В процессе тестирования на простом примере сессия работала

<?php
ini_set('session.save_handler', 'eaccelerator');
session_start();
if (isset($_SESSION['test'])) {
        echo "Stored value: " . $_SESSION['test'];
} else {
        echo "Storing session information";
        $_SESSION['test'] = 'Eaccelerator';
}

Но при тестировании на маджентовском сайте перестает работать сессия - похоже поддержку убрали не просто так.

Вы можете следить за обновлениями блога с помощью Atom/RSS и Telegram.

08 ноября 2012

Per-user конфигурация php в WHM/cPanel

SUPHP


Если вы используете suphp в cPanel, то у вас может возникнуть проблема, когда для разных сайтов потребуется различная конфигурация. Из коробки в cPanel конфигурация PHP берется из /usr/local/lib/php.ini. Чтобы создать per-user конфиг нужно:

  • создать файл /home/username/php.ini и добавить в него нужные переопределения относительно общего конфига /usr/local/lib/php.ini. Я туда дописал

    max_execution_time = 7200
  • создать файл /home/username/public_html/.htaccess и добавить в него

    SetEnv PHPRC /home/username/php.ini

Аналогично можно сделать, если иные настройки php нужно сделать не для всех хостов пользователя, а только для одного или нескольких субдоменов. В последнем случае .htaccess нужно положить в соответствующем docroot'е.

CGI/FastCGI


Если на сервере PHP работает в режиме CGI/FastCGI, то начиная с PHP 5.3.0 появилась поддержка INI-файлов в стиле .htaccess на уровне каталога. Для изменения параметров интерпретатора нужно:

  • создать файл .user.ini (имя файла зависит от значения параметра user_ini.filename) в docroot'e сайта.

    xdebug.remote_enable = On
    xdebug.remote_host = 192.168.1.115
    xdebug.remote_port = 9000
    xdebug.remote_mode = req
  • подождать пока истечет период обновления (зависит от значения user_ini.cache_ttl) или перезагрузить веб-сервер.

Вы можете следить за обновлениями блога с помощью Atom/RSS и Telegram.

26 июля 2010

Сокрытие версии апача и php в ответе сервера.

Понадобилось скрыть версии апача и php в ответе сервера. С ходу нагуглил решение для апача и php. Себе помечу как памятку.

Apache
ServerTokens ProductOnly
ServerSignature Off

PHP
expose_php = Off

Вы можете следить за обновлениями блога с помощью Atom/RSS и Telegram.