Полет нормальный. Без происшествий.
Переход на PHP7: работа над ошибками
Итак, у вас есть старенький, но уж очень милый сердцу сайт, который вы решаетесь из жалости (или, возможно, перечитав Хабра) перевести на PHP7. С волнением ожидая резкого роста производительности, вы смахиваете пыль с бедного сайта и решительно переключаете в панели управления хостингом версию PHP.
Если сайт уже давно не молод, то с большой долей вероятности чудо не произойдет. В лучшем случае начнут появляться разного рода ошибки, а в худшем — вы увидите белый экран, дзен веб-разработки. В этот момент хочется по-быстрому переключить все обратно и забыть о своей внезапной слабости.
Но предположим, что ваша сильная сторона — настойчивость, к тому же вы располагаете некоторым количеством времени для экспериментов. Давайте попробуем все починить.
Резервные копии
Делаем резервные копии сайта (а заодно и баз данных). Ведь кто не делает резервные копи — сам себе враг, верно? Для разного рода экспериментов имеет смысл добавить еще один сайт на хостинге и скопировать в него файлы, которые мы сейчас будем править.
Журналы ошибок
Настроим ведение журнала ошибок PHP в файл .htaccess (если он не был настроен ранее):
php_value display_errors 0
php_value log_errors 1
php_value error_log /home/vasya/domains/mysite.ru/logs/error.log
Работа с MySQL
Допустим, сайт использует базы данных, и вы видите ошибки вроде такой:
Fatal error: Uncaught Error: Call to undefined function mysql_connect()
Это оттого, что в современных версиях PHP (начиная с PHP 5.5.0) оригинальное расширение MySQL не поддерживается. Разработчики рекомендуют использовать MySQLi или PDO. Попробуем перейти на MySQLi, это просто:
Предположим, что сайт написан с использованием процедурного подхода, который представляет собой классический говнокод многие и сейчас считают лаконичным и эффективным решением. В таком случае, следующую устаревшую конструкцию для подключения к базе данных:
$link = mysql_connect(‘localhost’, $user, $password)
mysql_select_db($dbname, $link)
mysql_query(‘set names cp1251’)
можно заменить на:
$link = mysqli_connect(‘localhost’, $user, $password, $dbname)
mysqli_query($link, ‘set names cp1251’)
Другие популярные функции легко меняются на их аналоги с буквой ‘i’:
mysqli_fetch_array()
mysqli_fetch_row()
mysqli_fetch_assoc()
mysqli_fetch_array()
mysqli_num_rows()
mysqli_insert_id()
mysqli_close()
В результате этих несложных действий данные из БД должны успешно собираться и отправляться.
Кодировка
Настоящий олдскул — это сайт в CP1251 (как минимум). Всё превратилось в ромбики или прочие козяблики?

Скорее всего, достаточно будет указать кодировку в .htaccess таким образом:
php_value default_charset «cp1251»
Регулярные выражения
Также вы можете наблюдать ошибки следующего рода:
Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead
Это означает, что модификатор /e, который позволял передать произвольной функции результат регулярного выражения, теперь не поддерживается. В таких случаях рекомендуется использовать функцию preg_replace_callback
Допустим, у нас есть такое регулярное выражение:
с заменой на preg_replace_callback оно должно выглядеть вот так:
$string=preg_replace_callback(«/:([a-z]<1,10>):/», create_function(‘$matches’, ‘return print_smile($matches[1])’), $string)
здесь все просто, регулярное выражение теперь указывается в качестве первого аргумента (без модификатора /e, разумеется), а в качестве второго аргумента указывается анонимная функция (которая будет выполнена после применения регулярного выражения) с двумя аргументами: массив $matches, где будут сохранены данные, совпадающие с регулярным выражением и вызов внешней функции с аргументами. В данном примере внешняя функция называется print_smile и ей передается аргументом первое найденное вхождение. То, что в preg_replace было \1 (первое найденное вхождение) станет $matches[1] (если аргументов было больше, то будет $matches[2], $matches[3] и так далее).
Вот еще один пример, посложнее:
$out=preg_replace_callback(‘/ (.*?) /s’, create_function(‘$matches’, ‘return feed_out_sub_rm($matches[2], «‘.$base_prefix.’», «‘.$nick.’», «‘.$id_entry.’») ‘), $out)
здесь легко запутаться в кавычках, будьте внимательны.
Копаясь в регулярных выражениях, можно вспомнить еще про две функции, которые с версии PHP 5.3.0 считаются устаревшими (и не поддерживаются). Симптомы следующие:
Fatal error: Uncaught Error: Call to undefined function ereg_replace()
Если регулярное выражение в ereg_replace простое, то можно обойтись просто установкой граничных символов, как здесь:
Fatal error: Uncaught Error: Call to undefined function split()
Если регулярное выражение посложнее, то пробуем преобразовать к preg_split.
На этом пока все. Удачной отладки.
Много полезных материалов по теме можно найти на сайте разработчиков.
Если что-то не получается, или ваш случай совсем не похож на наши примеры — пишите комментарии, попробуем разобраться вместе.
Для того, чтобы оставлять комментарии к посту, авторизуйтесь, используя свой аккаунт в социальных сетях ВКонтакте/FaceBook, или аккаунт в Google/Яндекс.
Всем привет. Перенёс сайт на ВМ Centos 7.
Набор джентльмена: apache, php, mysql.
Запустил файл restore.php развернул бэкап, отдельно развернул дамп в бд. Захожу на сайт, получаю:
Следуя тому, что выдал гугль, в файле /bitrix/php_interface/dbconn.php добавил константу define(«BX_USE_MYSQLI», false), а в файле /bitrix/.settings.php изменил ‘\Bitrix\Main\DB\MysqlConnection’ на ‘\Bitrix\Main\DB\MysqliConnection’. Ошибка всё равно остаётся.
Были рекомендации
1) раскомментировать в php.ini строку «extension=php_mysqli.dll», но у меня её нет.
2) по пути «/etc/php.d/» создать файл «30-mysqli.ini» и добавить туда строку «extension=mysqli.so». Ошибка осталась. Я понять не могу, почему ошибка сохраняется.
phpinfo() отрабатывает хорошо.
Подскажите, в какую сторону можно ещё копнуть?)
При развертывании резервной копии сайта на Bitrix у себя на хостинге увидел ошибку:
Fatal error: Call to undefined function BitrixMainDBmysql_connect() in . on line 40
Как оказалось, на предыдущем хостинге использовался PHP 5.x, а на моем PHP 7.0, а mysql_connect «. устарело, начиная с версии PHP 5.5.0, и удалено в PHP 7.0.0. Используйте вместо него MySQLi или PDO_MySQL.«
В Bitrix нужно включить использование mysqli_connect следующим способом (подсказал знающий человек, сам бы долго разбирался)
- В конце файла itrixphp_interfacedbconn.php , перед ?> , нужно добавь строку define(«BX_USE_MYSQLI», true);
- В файле itrix.settings.php , в настройках
‘connections’ =>
array (
‘value’ =>
array (
‘default’ =>
array (
‘className’ => ‘\Bitrix\Main\DB\MysqlConnection‘,
‘host’ => ‘localhost’,
‘database’ => ‘dbName’,
‘login’ => ‘root’,
‘password’ => ‘123456’,
),
),
),
Заменить на ‘className’ => ‘\Bitrix\Main\DB\MysqliConnection‘,
Все заработало, Bitrix «завелся»)
Проблема описана еще в 2014 году на форуме Bitrix, и может возникнуть на старых проектах, в обновлении ядра 14.5.2 добавлена полная поддержка mysqli. Включать mysqli нужно отдельно для старого и нового ядра.