|
| |||||||||||||||||
PHP и WEB для новичков: Миграция с PHP 4 на PHP 7 и PHP 8Автор: Владислав Демьянишин
![]() Эта статья прежде всего для владельцев самописных сайтов, т.е. написанных своими руками на PHP. Многие когда-то на заре Интернета и серверов Apache с PHP увлеклись созданием собственных сайтов. С тех пор прошло у-у-у сколько много лет. И все бы ничего, но с появлением новых версий PHP 5 и PHP 7, желаешь того или нет, а модернизировать код своего сайта придется. В этой статье кратко собраны все актуальные нюансы доведения кода до соответствия версиям PHP 5, а от нее к PHP 7.
Данная статья не учит программированию. Предполагается, что читатель уже глубоко знаком с языком программирования PHP.
Итак, для экономии вашего времени я решил составить данный перечень советов по тем командам, которые в новых версиях PHP претерпели изменения. Сам долго сидел на старом проверенном годами коде, но жизнь заставила снова заняться изучением уже новых спецификаций языка. Кстати, как оказалось, в спецификации говорится одно, а на практике оказывается немного другое. С чем я и поделюсь с вами.
Изначально свои сайты я разрабатывал оффлайн и тестировал под Denwer. Поэтому при адаптации моих сайтов встала задача обеспечить, чтобы код и дальше успешно работал не только на реальном хостинге с PHP 7, но и на старом Denwer со всеми его недостатками. Кому как, а мне так работать комфортнее.
И еще одно: для тех, у кого код сайтов (не путать с кодировкой БД) был составлен в кодировке windows-1251 (cp1251), то в своей статье буду стараться учитывать и это.
Переход на PHP 5.6Следует заменить устаревшие команды работы с текстом. Например, вместо вызова функции htmlspecialchars с одним параметром, следует ее вызывать в соответствии с новым форматом, например, так:
htmlspecialchars($text, null, "windows-1251");
Вместо функций:
strtoupper($text);
strtolower($text);
теперь следует применять соответственно:
mb_strtoupper($text, $charset);
mb_strtolower($text, $charset);
ну и в таком духе.
Для тех, у кого весь php-код набран с комментариями в кодировке windows-1251, чтобы сохранить такое привычное удобство и дальше, в файле .htaccess указать команду:
php_value default_charset windows-1251
Переход на PHP 7Если ваш сайт ранее уже был подготовлен к переходу на PHP 5.6, то для его адаптации для PHP 7 осталось окончательно отказаться от использования платформы MySQL, которая на PHP 7 отсутствует. Придется переходить на MySQLi. На самом деле переход на MySQLi осуществляется легко.
Итак, в лице функционала MySQLi мы получаем все то же самое, что и в MySQL, но есть два способа применения этого функционала: процедурный, как у MySQL и объектный. Я выбрал объектный не помню уже почему, но на мой взгляд, он более логичный. Итак, начнем. Думаю, начиналось у всех, почти одинаково:
$db_settings = array(
'user' => ..., // имя пользователя БД
'password' => ..., // пароль пользователя БД
'database' => ..., // названиеБД
'server' => ..., // обычно "localhost"
'encoding' => 'cp1251' // требуемая кодировка на выходе БД
);
Вероятно, вы заметили параметр encoding - теперь он нам понадобится.
Нам пригодятся следующие переменные:
$mydb_mode = ''; // для хранения режима доступа к БД
// Определяем, если старый MySQL не доступен, включаем режим поддержки MySQLi
if (!function_exists('mysql_query')) $mydb_mode = 'mysqli'; // 'mysql' or 'mysqli'
$mydb = null; // будущий экземпляр объекта соединения с MySQLi
$mydbi_result = null; // будущий экземпляр результата MySQLi-запроса
$mydb_error = ''; // для описания возникающих ошибок
$mydb_errno = 0; // для кода возникающих ошибок
Теперь, чтобы понять разницу в подходах, рассмотрим отличия между старым способом соединения с БД и новым. Старый код до версии PHP 7 мог выглядеть и успешно работать, примерно, так:
// до PHP 5.x
function Connecting_DB() {
global $db_settings;
$link = @mysql_connect($db_settings["server"], $db_settings["login"], $db_settings["password"] );
if(!$link){
echo "невозможно подключиться к серверу: ".mysql_error()."";
exit;
}
if(!mysql_select_db($db_settings["db_name"] )){
echo "невозможно подключиться к БД: ".mysql_error()."";
exit;
}
}
Теперь его можно заменить так:
// для php7
function Connecting_DB( $dboption ) {
global $mydb_mode, $mydb, $mydbi_result, $mydb_error, $mydb_errno;
if ($mydb_mode == 'mysqli') {
$mydb = @new mysqli( $dboption['server'], $dboption['user'], $dboption['password'], $dboption['database'] );
// Проверяем соединение
if ($mydb->connect_errno) {
echo "невозможно подключиться к серверу: ". $mydb->connect_error ."";
exit;
}
if ($dboption['encoding'] != '')
// изменение набора символов на cp1251
if ( !$mydb->set_charset( $dboption['encoding'] ) ) {
echo "can't set database charset to ". $dboption['encoding'] .", error: ". $mydb->error;
}
// включаем, кому надо
//else echo "current database charset is ". $mydb->character_set_name();
}
else {
$link = @mysql_connect($dboption['server'], $dboption['user'], $dboption['password'] );
if(!$link){
echo "невозможно подключиться к серверу: ".mysql_error()."";
exit;
}
if(!mysql_select_db( $dboption['database'] )){
echo "невозможно подключиться к БД: ".mysql_error()."";
exit;
}
if ($dboption['encoding'] != '')
// включаем, кому надо
//mysql_query( "SET CHARACTER SET ". $dboption['encoding'] );
}
}
Успешное соединение с БД на PHP 7 нам гарантировано. Теперь необходимо обеспечить работу старого функционала, но минимальные правки все же придется сделать. Сначала подготовим прослойку функций с интерфейсом параметров, аналогичным MySQL, но одинаково успешно работающим и с Denwer и PHP 7. Достаточно объявить наиболее употребляемые команды:
// Получение информации о возникшей ошибке
function mydb_error() {
global $mydb_mode, $mydb, $mydbi_result, $mydb_error, $mydb_errno;
if ($mydb_mode == 'mysqli') {
if ($mydb_errno) $tmp = "MyDB error (".$mydb_errno."): ".$mydb_error;
else $tmp = '';
// при считывании ошибки очищаем ее
$mydb_error = '';
$mydb_errno = 0;
return $tmp;
}
else return mysql_error();
}
// Выполнение SQL-запроса
function mydb_query( $aquery ) {
global $mydb_mode, $mydb, $mydbi_result, $mydb_error, $mydb_errno;
if ($mydb_mode == 'mysqli') {
// Согласно руководству PHP касаемо MySQLi требуется очистка результата перед выполнением нового SQL-запроса. НО, почему-то, это вызывает ошибку. А если этого не делать, то все тип-топ.
//if ($mydbi_result) $mydbi_result->close(); // очищаем результат перед очередным запросом
$mydbi_result = $mydb->query( $aquery );
if (!$mydbi_result) {
$mydb_errno = $mydb->errno;
$mydb_error = $mydb->error;
}
}
else return mysql_query( $aquery );
}
// Возвращает количество рядов результата запроса
functionmydb_num_rows( $res ) {
global $mydb_mode, $mydb, $mydbi_result, $mydb_error, $mydb_errno;
if ($mydb_mode == 'mysqli') return $mydbi_result->num_rows;
else return mysql_num_rows( $res );
}
// Аналогичнастаройкоманде mysql_result
function mydb_result($res, $row_index, $field_name ) {
global $mydb_mode, $mydb, $mydbi_result, $mydb_error, $mydb_errno;
if ($mydb_mode == 'mysqli') {
$mydbi_result->data_seek( $row_index );
// получаем ассоциативный массив строки результата запроса
$tmp = $mydbi_result->fetch_assoc();
return $tmp[$field_name];
}
else {
mysql_data_seek( $res, $row_index );
$tmp = mysql_fetch_assoc( $res );
return $tmp[$field_name];
}
}
Ну и куда же без нее:
function my_mysql_real_escape_string( $text ) {
global $mydb_mode, $mydb;
if ($mydb_mode == 'mysqli') return $mydb->real_escape_string( $text );
else return mysql_real_escape_string( $text );
}
На примере этих функций видно, как легко для PHP 7 адаптировать работу с БД.
Переход на PHP 8Разработчики убеждены, что выжали максимум производительности в 7-й версии и сделали PHP самой быстрой из динамических ЯПов. Но чтобы двигаться дальше, т.е. для получения более высокого уровня производительности, необходим JIT-компилятор. Следует отметить, что для простых сайтов, да и для сложных применение JIT не особенно повышает скорость обработки запросов (возможно даже замедление). JIT будет особенно полезен и эффективен там, где необходимы вычисления в большом объеме. Так что, возможно, уже не далек тот день, когда самые отчаянные начнут создавать ИИ на PHP.
Активировать JIT можно в настройках opcache в файле php.ini.
Вкратце, это выглядит так:
1. Обычный код сайта...
2. Подготовка некоторого весьма трудоемкого кода для JIT-компиляции.
3. Выполнение скомпилированного JIT-кода.
4. ...обычный код сайта.
Таким образом, в нужном месте применяем JIT-компиляцию для трудоемкого кода, чтобы он отработал максимально эффективно на оборудовании, на котором был скомпилирован, а дальше снова обычный код.
Именно поэтому для мало нагруженных систем JIT-компиляция ни к чему. Подробнее о JIT можно почитать тут (https://habr.com/ru/post/515216/).
А если что-то осталось не ясно, заходите на https://www.php.net и читайте руководство более подробно.
© Владислав Демьянишин На нашем сайте можно не только бесплатно скачать игры, но и документацию и книги по программированию на MIDLetPascal, Turbo Pascal 6, Turbo Pascal 7, Borland Pascal, по программированию устройств Sound Blaster, Adlib, VESA BIOS, справочник Norton Guide и много другой полезной информации для программистов, включая примеры решения реальных задач по созданию резидентных программ. Журнал > Программирование > PHP и WEB для новичков (HTML, JavaScript, PHP, MySQL) > PHP и WEB для новичков: Миграция с PHP 4 на PHP 7 и PHP 8
| ||||||||||||||||||
|
||||||||||||||||||