Site Tools


php

PHP простые примеры и тесты кода
PHP конструкция кода
PHP перечисление всего

Не сортировано

Установка времяни

В php.ini строка date.timezone = Etc/GMT-4
поддерживаемые зоны (Москва == Etc/GMT-4)

$date = date('D, j M Y H:i:s ', time());
print($date);

Установка модулей

PHP может быть установленно из исходных кодов и скомпилировано в ручную или оно может быть установленно сразу бинарником.

Бинарник

Встроенные модули

При установке бинарником, все включенные в PHP модули, устанавливаются вместе с ним, но их необходимо включать. К примеру в /etc/php/php.d находятся текстовые файлы, которые инклюдятся при старте и в них прописаны подключения к модулям. Достаточно найти необходимый модуль и расскоментировать его.

Добавление модуля с phpize

находим, скачиваем, компилируем модуль.

wget http://download.suhosin.org/suhosin-0.9.32.1.tar.gz
...
yum install php-devel
phpize
./configure
make && make install

Подключаем модуль к php

echo ‘extension=suhosin.so’ > /etc/php.d/suhosin.ini
Перезагрузим веб-сервер
Добавления модуля с PECL

Необходимы пакеты → php-devel и php-pear

pecl install mod_name 

из исходных кодов

Встроенные модули

При установке PHP из исходных кодов, он компилируется в бинарник только с теми модулями, которые Вы укажите. Чтобы добавить в PHP модуль, следует перейти в папку от куда Вы его компилировали и перекомпелировать вновь, указав все текущие модули (можно посмотреть в phpinfo()→Configure Command) и новые модули. К примеру ./configure –with-xsl

Установлен ли модуль

На примере iconv

php -m | grep  iconv
php -r 'echo function_exists("iconv")."\n";'
Установлена ли функция

# php -a php > if(function_exists('json_decode')) {echo “function is enabled”;}else {echo “function is not enabled”;}

Устанавливаем модули
  91	11:21	make search name="php52-tokenizer"
  92	11:22	cd /usr/ports/devel/php52-tokenizer
  93	11:22	make install
  78	17:29	whereis ImageMagick
  79	17:29	cd /usr/ports/graphics/ImageMagick
  80	17:30	make install clean

Zend

http://www.zend.com/en/products/guard/downloads

  1. ZendGuardLoader и ZendOptimizer не обратно совместимы. Если приложение просит ZendOptimizer, то при установке ZendGuardLoader и обращение к сайту Вам будет сказано Fatal error: Incompatible file format: The encoded file has format major ID 1, whereas the Loader expects. Следовательно ищем версию которую требует приложение и ставим.
  2. ZendGuardLoader и ZendOptimizer подключаются не сложно. Достаточно скачать бинарник и прописать его в конфиги, чтобы php знал где его загружать.

Add the following line to your php.ini file:

 zend_extension=<full_path_to_ZendOptimizer.so>

x86

wget http://downloads.zend.com/optimizer/3.3.9/ZendOptimizer-3.3.9-linux-glibc23-i386.tar.gz # ZendOptimizer совместим с версиями PHP только 5.2 или ниже
wget http://downloads.zend.com/guard/5.5.0/ZendGuardLoader-php-5.3-linux-glibc23-i386.tar.gz

x64

wget http://downloads.zend.com/optimizer/3.3.9/ZendOptimizer-3.3.9-linux-glibc23-x86_64.tar.gz
wget http://downloads.zend.com/guard/5.5.0/ZendGuardLoader-php-5.3-linux-glibc23-x86_64.tar.gz
Zend For FreeBSD
cd /usr/ports/devel/ZendOptimizer
make install clean
find / -iname "*ZendOptimizer*" #Ищем куда поставился
vi /usr/local/etc/php.ini # и дописываем строчку:
zend_extension="Путь до ZendOptimizer.so"
/usr/local/etc/rc.d/apache22 restart # не забываем рестартовать.

Ошибки

Shared object "libm.so.6" not found, required by "ZendOptimizer.so

Сообщает нам, что не найдена библиотека и если ставится на FreeBSD, то вы пытаетесь установить Zend предназначенный для Linux а не FreeBSD.

500 при zend и ioncube

Сначала подключаем ioncube и только потом zend. Иначе, получим 500-тую ошибку.

Спец Zend Ошибки при открытии сайта
Fatal error: Incompatible file format: The encoded file has format major ID 0, whereas the Optimizer expects 2 in

Файлы закачены не корректно и некторые символы изменились в процессе передачи. Включаем бинарный режим или закачиваем через архив.

ioncube

  1. Достаточно подключить как zend_extension = /usr/local/lib/php/20060613/ioncube_loader_fre_5.2.so
  2. Но если возникают сложности, то пихаем в директорию с сайтом и запускаем loader-wizard.php

ВАЖНО - Подключаем выше (перед) ZendOptimizer (Если он вообще подключен)

DownGrade PHP

Инсталяция из архива

php релизы → http://ru.php.net/releases/
Инструкция по установке → http://www.php.net/manual/ru/install.unix.php
наиболее общие ошибки, возникающие на этапе сборки. → http://php.net/manual/ru/faq.build.php

Необходимы пакеты → bison и flex

For CentOS:

Суть проста: 1) Удаляем все php 2) Запрещаем Yum работать с php5.3 3) Устанавливаем php

Пример:

yum remove php php-*
echo exclude = php*5.3* >> /etc/yum.conf
yum install php

Derictive

.htaccess

php_flag name on|off # Для boolian значений
php_value name value # Для остальных значений

VirtualHost

php_admin_flag name on|off # Для boolian значений
php_admin_value name value # Для остальных значений

объяснение → PHP_INI_ALL, PHP_INI_PERDIR, or PHP_INI_SYSTEM → http://www.php.net/manual/ru/configuration.changes.modes.php http://php.net/manual/en/configuration.changes.php
http://www.php.net/manual/en/ini.list.php → рус → http://php.net/manual/ru/ini.list.php

Вопросы

Собственный php.ini для сайта и параметры php

Configuration File (php.ini) Path /etc/
Loaded Configuration File /var/www/grade/data/php-bin/php.ini

Для каких целей создается дополнительный php.ini файл для пользователя?
mbstring.func_overload=2 при этом не работает не в VH не в /etc/php.ini

PHP как CGI

Особенности

Основная польза:

  • Можем использовать для любого сайта, свою, любую версию php
  • Можем заранее компилировать интерпритатор на стороннем сервере или найти скомпилированный. #file php поможет Вам узнать ОС и битность для которой скомрилирован php

Основной минус:

  • CGI съедает больше ресурсов и нежелателен для высоконагруженных сайтов.
Пример

Кратко:

  1. Каччаем дистрибутив Архив дистрибутивов
  2. Компилируем c –prefix=/some/some/MyDir/myphp , make clean, make, make install
  3. ln -s /some/some/MyDir/myphp/bin/php /some/some/www/testim2.ru/cgi-bin/
  4. vi /some/some/www/testim2.ru/.htaccess
AddHandler php-cgi .php4 .php 
Action php-cgi /cgi-bin/php

1
2

Как определить, что сайт рабоате по CGI

  1. Указывается в phpinfo.php→Server API
  2. php -v # в первой строке, после версии указан cli или cgi. Соответственно, для cgi может использоваться только cgi
разница при использование ISPmanager

diff -r /etc/httpd/conf/httpd.conf /root/testim/1/httpd/conf/httpd.conf

244,246d243
< 	ScriptAlias /php-bin/ /var/www/test/data/php-bin/
<  	ScriptAlias /cgi-bin/ /var/www/test/data/www/testim.ru/cgi-bin/
< 	AddHandler php-cgi .php .php3 .php4 .php5 .phtml
1039d1035
< 	Options +ExecCGI

PHP как FastCGI

С использованием php-fpm: =1==2=
С использованием spawn-fcgi: =1= =2=

  1. Устанавливаем php-fpm или spawn-fcgi (В последних php версиях, php-fpm встроен, кажется)
  2. Скачиваем интересующий нас дистрибутив php
  3. Компилируем c –prefix=/some/some/MyDir/myphp , make clean, make, make install
  4. Задаем настройки запуска и путь к php-дистрибутиву для php-fpm или spawn-fcgi
  5. Запускаем и смотрим, что приложение успешно работает

Учим работать с FastCGI:
Nginx
Apache

Debug

Отображение ошибок
error_reporting(E_ALL);
ini_set('display_errors', '1');
Отображение строк
var_dump($var);
тайминг
$time_start = microtime(true);
// Спим некоторое время
usleep(100);
$time_end = microtime(true);
$time = $time_end - $time_start;
echo "<br>";
echo $time
eAccelerator

Пример отлова ошибок

              try {
                      if(strlen($sql) > 9000){
                             throw new Exception("Big Query");
              }
                      return $this->link->query($sql);
              }catch(Exception $e) {
                      $FileHandle = fopen("/home/u/user/MySQLbigQuery.log","a");
                      fwrite($FileHandle,var_export($e->getMessage(),true));
                      fwrite($FileHandle,var_export($e->getTraceAsString(),true));
                      fwrite($FileHandle,var_export($sql,true));
                      return $this->link->query($sql);
              }

или

try {throw new \Exception("Strace");}catch(\Exception $e){file_put_contents('/home/dev/konovalov/var.log', print_r(['Trace: ' => $e->getTraceAsString()], true), FILE_APPEND);}

Трасировка вызова:

error_reporting(E_ALL); ini_set('display_errors', '1'); throw new Exception("Strace");

Логируем запросы

$FileHandle = fopen("/home/dev/konovalov/var.log", "a");
fwrite($FileHandle, "\nVVV ===== " . date('Y-m-d H:i:s', time()) ." ===== VVV\n");
fwrite($FileHandle, print_r(['request' => $_REQUEST], true));

fwrite($FileHandle, "\nurl: http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]\n");
fwrite($FileHandle, "\nrequest:\n");
fwrite($FileHandle, var_export($_REQUEST, true));
fwrite($FileHandle, "\nget:");
fwrite($FileHandle, var_export($_GET, true));
fwrite($FileHandle, "\npost:");
fwrite($FileHandle, var_export($_POST, true));
fwrite($FileHandle, "\ncookie:");
fwrite($FileHandle, var_export($_COOKIE, true));
...
fwrite($FileHandle, "\nsendHeaders:");
fwrite($FileHandle, var_export(headers_list(), true));

Логируем 2

file_put_contents("/tmp/V45NcnhCU2", print_r($message, 1), FILE_APPEND);
file_put_contents("~/debug.log", print_r("Cron: LINE:" . __LINE__ . " PID:" . posix_getpid() . " Date:" . date('Y-m-d H:i:s',time()) . "\n" , 1), FILE_APPEND);
file_put_contents("log.log", print_r("addr:$_SERVER[REMOTE_ADDR] date:" . date('Y-m-d H:i:s',time()) . "\n", 1), FILE_APPEND);

Discussion

Constantin Conovaloff, 2014/10/02 20:44

Хитрый способ заставить функцию выполняться самой, самой последней

        register_shutdown_function(function () {
            // make sure "flush()" is called last when there are multiple shutdown functions
            register_shutdown_function([$this, 'flush'], true);
        });
Constantin Conovaloff, 2014/10/02 22:49

Дебаг использование функции register_tick_function

<?php

declare(ticks=1);

$log_to_file = true;
$log_to_stdout = false;

$FileHandle = Null;

if ($log_to_file) {
    $FileHandle = fopen("/home/dev/konovalov/var.log", "a");
    fwrite($FileHandle, "\nVVV ===== " . date('Y-m-d H:i:s', time()) ." ===== VVV\n");
    fwrite($FileHandle, "POST:\n" . print_r($_POST, true));
}

register_tick_function(function() use ($FileHandle, $log_to_file, $log_to_stdout) {
    $backtrace = debug_backtrace();
    $line = $backtrace[0]['line'] - 1;
    $file = $backtrace[0]['file'];

    if ($file == __FILE__) return;

    static $fp, $cur, $buf;
    if (!isset($fp[$file])) {
        $fp[$file] = fopen($file, 'r');
        $cur[$file] = 0;
    }

    if (isset($buf[$file][$line])) {
        $code = $buf[$file][$line];
    } else {
        do {
            $code = fgets($fp[$file]);
            $buf[$file][$cur[$file]] = $code;
        } while (++$cur[$file] <= $line);
    }

    $line++;
    if ($log_to_stdout) {
        echo "\n$file on line $line" . PHP_EOL;
        echo "$code" . PHP_EOL;
    }

    if ($log_to_file) {
        fwrite($FileHandle, "\n$file on line $line" . PHP_EOL);
        fwrite($FileHandle, "$code" . PHP_EOL);
    }
});

include('./index.php');
Constantin Conovaloff, 2015/01/22 13:27

получить fatal error

      register_shutdown_function(function() {
              file_put_contents('/home/dev/konovalov/var.log', print_r(['error_get_last:' => error_get_last()], true), FILE_APPEND);
      });
Constantin Conovaloff, 2015/01/31 21:41

time microseconds difference (profiling)

  $curTime = microtime(true);
  $timeConsumed = round(microtime(true) - $curTime,3) * 1000;
Constantin Conovaloff, 2015/02/01 20:38

Правило присвоения

  1. Все кроме объектов присваивается по значению.
  2. Объекты присваиваются по ссылке
  3. Объект можно присвоить по значению через clone
<?php

class cl_1{
    public $obj;
    
    public function __construct($obj)
    {
        $this->obj = $obj;
    }
}


class cl_2{
    public $name;
    
    public function __construct($name)
    {
        $this->name = $name;
    }
}


$first = new cl_2('First');
$main = new cl_1($first);

< $main->obj->name;  # First

$tmp = $main->obj;
$tmp->name = 'Second';

< $tmp->name;  # Second
< $main->obj->name;  # Second
Constantin Conovaloff, 2015/04/08 12:50

assert

assert_options(ASSERT_ACTIVE, 1);  # Включаем
assert_options(ASSERT_CALLBACK, [$this, 'assertException']);  # указываем callback который должен исполниться
assert(true);   # callback _не_ срабатывает
assert(false);  # callback срабатывает
Constantin Conovaloff, 2015/04/08 22:57

генерация бинарных данных

$data = '';
for  ($i = 0; $i < 1000; $i++) {
    $buffer_char = '';
    for ($z = 0; $z < 32; $z++) {
        $buffer_char .= (string)rand(0, 1);
    }
    
    $data .= pack('H*', base_convert($buffer_char, 2, 16));
}

var_dump($data);
Constantin Conovaloff, 2015/04/24 19:09

http://php.net/manual/ru/book.spl.php

Constantin Conovaloff, 2015/06/18 15:17

php execute command with return control

var_dump('start');
var_dump(file_get_contents('/tmp/wow'));

system("vim /tmp/wow > `tty`");

var_dump('end');
var_dump(file_get_contents('/tmp/wow'));
Constantin Conovaloff, 2015/08/20 19:03

Получение полной трассировки сообщения

class Some{
    function wow($a){
        throw new Exception('Bad');
    }
}

$some = new Some();
try{
    $some->wow('ssssssssssssssssssssssssssssssssssssssssssssssssssa');
} catch (\Exception $e) {
    $result = print_r($e->getTrace(), true);
}

var_dump($result);

result:

string(377) "Array
(
    [0] => Array
        (
            [file] => /home/conovaloff/data/PhpstormProjects/hacks/error.php
            [line] => 11
            [function] => wow
            [class] => Some
            [type] => ->
            [args] => Array
                (
                    [0] => ssssssssssssssssssssssssssssssssssssssssssssssssssa
                )

        )

)
"
Constantin Conovaloff, 2016/03/25 18:44

Установка нового php-fpm на сервер, где уже существует другие php-fpm

Условия:

  • на сервере работает высоконагруженный сайт на php5.4
  • Идет связка nginx –> socket –> php-fpm –> site files

Задача:

  • Обновить php сайта до php7
  • Сайт при этом не должен простаивать

Решение:

  • Скачивание php7 –> компиляция из исходников в отдельную директорию, без конфликтов с текущей версией. –> запуск на отдельном сокете\порту.
  • Добавление тестового хоста в nginx, который будет обращаться к новому php.
  • Разработчики через тестовый хост убеждаются в корректности работы сайта на новой версии php.
  • Production переключается на новый php-fpm

Скачиваем новую версию

Инструкция взята отсюда: https://www.howtoforge.com/tutorial/how-to-install-php-7-on-debian/

### Получаем ссылку на странице http://php.net/downloads.php
# mkdir /usr/local/src/php7-build ; cd /usr/local/src/php7-build
# wget http://uk1.php.net/get/php-7.0.4.tar.gz/from/this/mirror ; mv ./mirror ./mirror.tar.gz
# tar -xzvf mirror.tar.gz
# chown -R root:root ./php-7.0.4 ; cd php-7.0.4/
# apt-get install libfcgi-dev libfcgi0ldbl libjpeg-turbo8-dev libmcrypt-dev libssl-dev libc-client2007e libc-client2007e-dev libxml2-dev libbz2-dev libcurl4-openssl-dev libjpeg-dev libpng12-dev libfreetype6-dev libkrb5-dev libpq-dev libxml2-dev libxslt1-dev

### либо смотрите в сторону auto-apt
### Пакет libjpeg-turbo8-dev может называется по другому
# ln -s /usr/lib/libc-client.a /usr/lib/x86_64-linux-gnu/libc-client.a
### Местные хаки пошли 
# ./configure --help
### опционально посмотреть параметры
# ./configure --prefix=/opt/php-7.0.4 --with-pdo-pgsql --with-zlib-dir --with-freetype-dir --enable-mbstring --with-libxml-dir=/usr --enable-soap --enable-calendar --with-curl --with-mcrypt --with-zlib --with-gd --with-pgsql --disable-rpath --enable-inline-optimization --with-bz2 --with-zlib --enable-sockets --enable-sysvsem --enable-sysvshm --enable-pcntl --enable-mbregex --enable-exif --enable-bcmath --with-mhash --enable-zip --with-pcre-regex --with-pdo-mysql --with-mysqli --with-mysql-sock=/var/run/mysqld/mysqld.sock --with-jpeg-dir=/usr --with-png-dir=/usr --enable-gd-native-ttf --with-openssl --with-fpm-user=www-data --with-fpm-group=www-data --with-libdir=/lib/x86_64-linux-gnu --enable-ftp --with-imap --with-imap-ssl --with-kerberos --with-gettext --with-xmlrpc --with-xsl --enable-opcache --enable-fpm
# make
# checkinstall  # погуглите, это лучше чем make install 
# cp /usr/local/src/php7-build/php-7.0.4/php.ini-production /opt/php-7.0.4/lib/php.ini
# cp /opt/php-7.0.4/etc/php-fpm.conf.default /opt/php-7.0.4/etc/php-fpm.conf
# cp /opt/php-7.0.4/etc/php-fpm.d/www.conf.default /opt/php-7.0.4/etc/php-fpm.d/www.conf
# vi /opt/php-7.0.3/etc/php-fpm.conf
### uncommented pid = run/php-fpm.pid
# vi /opt/php-7.0.3/etc/php-fpm.d/www.conf
### uncommented listen = 127.0.0.1:8007 # или иной порт\сокет
# vi /etc/init.d/php-7.0.3-fpm
#! /bin/sh
### BEGIN INIT INFO
# Provides:          php-7.0.3-fpm
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts php-7.0.3-fpm
# Description:       starts the PHP FastCGI Process Manager daemon
### END INIT INFO
php_fpm_BIN=/opt/php-7.0.3/sbin/php-fpm
php_fpm_CONF=/opt/php-7.0.3/etc/php-fpm.conf
php_fpm_PID=/opt/php-7.0.3/var/run/php-fpm.pid
php_opts="--fpm-config $php_fpm_CONF"
wait_for_pid () {
        try=0
        while test $try -lt 35 ; do
                case "$1" in
                        'created')
                        if [ -f "$2" ] ; then
                                try=''
                                break
                        fi
                        ;;
                        'removed')
                        if [ ! -f "$2" ] ; then
                                try=''
                                break
                        fi
                        ;;
                esac
                echo -n .
                try=`expr $try + 1`
                sleep 1
        done
}
case "$1" in
        start)
                echo -n "Starting php-fpm "
                $php_fpm_BIN $php_opts
                if [ "$?" != 0 ] ; then
                        echo " failed"
                        exit 1
                fi
                wait_for_pid created $php_fpm_PID
                if [ -n "$try" ] ; then
                        echo " failed"
                        exit 1
                else
                        echo " done"
                fi
        ;;
        stop)
                echo -n "Gracefully shutting down php-fpm "
                if [ ! -r $php_fpm_PID ] ; then
                        echo "warning, no pid file found - php-fpm is not running ?"
                        exit 1
                fi
                kill -QUIT `cat $php_fpm_PID`
                wait_for_pid removed $php_fpm_PID
                if [ -n "$try" ] ; then
                        echo " failed. Use force-exit"
                        exit 1
                else
                        echo " done"
                       echo " done"
                fi
        ;;
        force-quit)
                echo -n "Terminating php-fpm "
                if [ ! -r $php_fpm_PID ] ; then
                        echo "warning, no pid file found - php-fpm is not running ?"
                        exit 1
                fi
                kill -TERM `cat $php_fpm_PID`
                wait_for_pid removed $php_fpm_PID
                if [ -n "$try" ] ; then
                        echo " failed"
                        exit 1
                else
                        echo " done"
                fi
        ;;
        restart)
                $0 stop
                $0 start
        ;;
        reload)
                echo -n "Reload service php-fpm "
                if [ ! -r $php_fpm_PID ] ; then
                        echo "warning, no pid file found - php-fpm is not running ?"
                        exit 1
                fi
                kill -USR2 `cat $php_fpm_PID`
                echo " done"
        ;;
        *)
                echo "Usage: $0 {start|stop|force-quit|restart|reload}"
                exit 1
        ;;
esac
Constantin Conovaloff, 2016/03/28 14:19

Установка нового расширения для одного из многих php-fpm на сервере

Условия:

  • на сервере работает несколько php-fpm серверов скомпилированных в ручную

Задача:

  • добавить extension для конкретного php-fpm сервера (бинарники расположены в prefix=/opt/php-7.0.3)

Решение:

  • скачиваем исходные коды расшерения
  • используем phpize из php-fpm для которого мы устанавливаем расширение ### /opt/php-7.0.4/bin/phpize
  • компилируем с указанием параметров ### –prefix=/opt/php-7.0.3 –with-php-config=/opt/php-7.0.4/bin/php-config
  • make && checkinstall
Constantin Conovaloff, 2016/03/28 17:34

Установка нового вкомпилируемого расширения (модуля) для одного из многих php-fpm на сервере

Условия:

  • на сервере работает несколько php-fpm серверов скомпилированных в ручную

Задача:

  • добавить модуль для конкретного php-fpm сервера (бинарники расположены в prefix=/opt/php-7.0.3)
  • Исходные коды используемые для компиляции предыдущей версии хранятся в /usr/local/src/php7-build/php-7.0.4

Решение:

  • Получаем configure предыдущей версии
/opt/php-7.0.3/bin/php -i | grep -i configure
  • Заходим в директорию предыдущей компиляции и производим перекомпиляцию тех же исходных кодов.
# ./configure # много текста из предыдущего configure
# make && checkinstall  # перед этим можно удалить предыдущий пакет dpkg -r name_package или нанести поверх.
# /etc/init.d/php-7-fpm restart
Constantin Conovaloff, 2016/04/07 17:31

Найти встроенные классы

Проблема:

  • установили модуль php, а документации нет.

Вопрос:

  • Что импортировать, какой класс использовать?

Ответ:

  • Можно найти класс через список объявленных: php -r 'print_r(get_declared_classes());'
Constantin Conovaloff, 2017/04/13 15:03
if (is_dir(ABSPATH . 'forDevelope/gitignore_dir')) {
    define('GITIGNOREPATH', ABSPATH . 'forDevelope/gitignore_dir/');

    function custom_exception_handler($exception) {
        file_put_contents(GITIGNOREPATH . '/var.log', print_r(['custom_exception_handler exception:' => print_r($exception, true)], true), FILE_APPEND);

        echo '<table>';
        echo($exception->xdebug_message);
        echo '</table>';
    }
    set_exception_handler('custom_exception_handler');

    ini_set('error_reporting', E_ERROR);
    function fatal_handler() {
        $error = error_get_last();
        file_put_contents(GITIGNOREPATH . '/var.log', print_r(['Last error:' => print_r($error, true)], true), FILE_APPEND);
    }
    register_shutdown_function("fatal_handler");
}
You could leave a comment if you were logged in.
php.txt · Last modified: 2017/10/31 01:22 by conovaloff

Page Tools