Перевод kohana с php 5 на php 7

Исторически сложилось, что jeka.by был написан на фреймворке kohana 3.2 и использовал как и все на то время php 5 (то ли php 5.2 то ли 5.3). 

На дворе 2017 год, а, значит, давно пора переходить на php 7.

Тут я напишу, какие изменения пришлось внести в код проекта. 

1. Я обновил Kohana до последней стабильной 3.3.0 версии. 

a) Заменил все модули на новые. А также заменил папку system. Переименовал часть своих папок и обращение в index.php, bootstap.php, чтобы каталоги и имена классов начинались с прописной буквы вместо строчной, пример: 

require SYSPATH.'classes/kohana/core'.EXT;

на 

require SYSPATH.'classes/Kohana/Core'.EXT;
частично исправлены конфиги новых модулей (их переопределение), т.к. модули 3.3.0 иногда имеют др. параметры

b) В kohana 3.3 удалён метод:

Request::current()->redirect()

вместо него нужно везде прописать редирект в виде:  

HTTP::redirect(url);

2. В php 7 наконец таки удалена поддержка mysql extension (нужно использовать mysqli или pdo). В то же время в kohana mysqli driver ещё официально не появился!

Поэтому нам нужно найти и подключить модуль mysqli для kohana. Я взял модуль на github https://github.com/tomlankhorst/kohana-3.3-mysqli

Подключил модуль как обычно в application/bootstrap.php в массиве Kohana::modules:

'mysqli' => MODPATH.'mysqli

А так же нужно изменить тип адаптера в application/config/database.php с MySQL на MySQLi.


3. Одну строку номер 121 в файле modules/pagination/classes/Kohana/Pagination.php нужно обновить в соответствии с синтаксисом php 7, добавить фигурные скобки: $config_file->{$config['group']}:

-		while (isset($config['group']) AND isset($config_file->$config['group']))
+		while (isset($config['group']) AND isset($config_file->{$config['group']}))

Иначе будет ошибка ErrorException [ Notice ]: Array to string conversion в классе Pagination:

Ошибка в классе Pagination "Array to string conversion" в Kohana 3 php 7


4. Следующая ошибка вывалится в kohana только в том случае, если вы используете Memcache расширение.

Memcache PHP extention not loaded

Ошибка возникает, т.к. данное расширение не выпущено разработчиками под 7-ую версию php (можно попробовать собрать ручками, но готовый пакет не предоставляется).

Как альтернатива, теперь будем использовать memcached. Соответственно, нужно найти и загрузить модуль memcached для kohana. Я взял вот этот модуль с github - https://github.com/gimpe/kohana-memcached

Кроме подключения модуля в bootstrap.php, не забываем исправить driver в конфиге application/config/cache.php c memcache на memcached.


5. У меня в kohana использовался ckeditor вместе с ckfinder для загрузки и просмотра картинок на сервере. При попытке ckfinder "Просмотреть на сервере" возникает ошибка в kohana "A non well formed numeric value encountered" в файле assets/vendors/ckfinder/core/connector/php/php5/Utils/Misc.php. См. скриншот:

Kohana CKFinder error

Ошибка не в ядре kohana, а в 3rdparty. Ошибка (варнинг) возникает в функции returnBytes:

/**
 * convert shorthand php.ini notation into bytes, much like how the PHP source does it
 * @link http://pl.php.net/manual/en/function.ini-get.php
 *
 * @static
 * @access public
 * @param string $val
 * @return int
 */
public static function returnBytes($val) {
	$val = trim($val);
	if (!$val) {
		return 0;
	}
	$last = strtolower($val[strlen($val)-1]);
	switch($last) {
		// The 'G' modifier is available since PHP 5.1.0
		case 'g':
			$val *= 1024;
		case 'm':
			$val *= 1024;
		case 'k':
			$val *= 1024;
	}

	return $val;
}

Это происходит в момент когда мы пытаемся в php 7.1 (в php 7.0 всё ок!) умножить строку на число:

'128M' * 1024

Решением является вставить перед констукцией switch приведение к типу integer:

$val = (int) $val;

Это не бага, а фича php 7.1 - https://wiki.php.net/rfc/invalid_strings_in_arithmetic:

Warn about invalid strings in arithmetic 

при выполнении арифметических операций с невалидными строками будет варнинг с текстом "Warn about invalid strings in arithmetic". В зависимости от уровня настроек может быть выброшен exception.


6. Следующая ошибка может возникнуть в неожиданный момент, когда что то пошло не так.

ErrorException [ Fatal Error ]: Uncaught TypeError: Argument 1 passed to Kohana_Kohana_Exception::handler() must be an instance of Exception, instance of Error given

Ошибка в php 7 kohana связана с тем, что в php 7 внесены изменения в механизм обработки ошибок.

Как пофиксить? Красивой альтернативы, обеспечивающей обратную совместимость, сообщество kohana еще не предлагало. Есть простой вариант с удалением typehint. Нужно в классе system/classes/Kohana/Kohana/Exception.php удалить во всех объявлениях функций ожидаемый тип аргумента Exception, т.е. вместо:

function handler(Exception $e)
function _handler(Exception $e)
function log(Exception $e,
function text(Exception $e)
function response(Exception $e)

Делаем:

function handler($e)
function _handler($e)
function log($e,
function text($e)
function response($e)

 Подробнее см. commit в kohana core.

Это весь список ошибок и их фиксов, которые возникли у меня при миграции kohana с php 5 на php 7 (php 7.0) на примере jeka.by.

UPD 1 июня 2022:

Пользуйтесь тулзами анализа кода, такими как phpcs со стандартом PHPCompatibility (нужно установить отдельно), чтобы найти проблемы совместимости с новыми версиями php. Полезно для всех проектов, не только kohana.

Несколько примеров (в моем случае phpcs установлен через composer как dev зависимость в самом проекте):

php vendor/bin/phpcs --standard=PHPCompatibility application/classes  --runtime-set testVersion 7.3 -n

php vendor/bin/phpcs --standard=PHPCompatibility modules  --runtime-set testVersion 7.4 -n

Запуск первой phpcs команды проверит все файлы внутри директории application/classes на совместимость с php 7.3 и выведет ошибки если они есть: в каком файле и какой строке есть проблема. Вторая команда - проверит все php-файлы в директории modules на совместимость с версией php 7.4.

Kohana php 7.4 migration:

modules/orm/classes/Kohana/ORM.php :: ErrorException в методе has

ErrorException [ Warning ]: count(): Parameter must be an array or an object that implements Countable.

Kohana php 7.4 migration: ErrorException [ Warning ]: count(): Parameter must be an array or an object that implements Countable.

Ведь второй параметр $far_keys может быть просто id'шником, на который нельзя сделать count, исправить можно так:

Kohana adopt for php 7.4: Kohana/ORM.php function has - param must be an array or countable objects

Ошибки касательно kohana-ckfinder

ErrorException [ Deprecated ]: The each() function is deprecated. This message will be suppressed on further calls

Kohana CKFinder ErrorException [ Deprecated ]: The each() function is deprecated. This message will be suppressed on further calls

Нужно избавиться от устаревшей функции each в файле assets/vendors/ckfinder/core/connector/php/php5/Core/Config.php:

Строку:

while (list($_key,$_resourceTypeNode) = each($GLOBALS['config']['ResourceType'])) {

Меняем на:

foreach ($GLOBALS['config']['ResourceType'] as $_resourceTypeNode) {

 

 
Поисковые запросы, по которым приходили пользователи
 
 
 
 

icon Комментарии 1

 ZardoZ 5 лет назад
Чтобы не нужно было делать много правок в своем коде и коде старых модулей, правим в файле modules/orm/classes/Kohana/ORM.php 44 строку
-$model = 'Model_'.$model;
+$model = 'Model_'.ucfirst($model);
Ваш комментарий к статье.. (для авторизованных)

ctrl+enter

icon Вход в систему

зарегистрироваться
НОВЫЕ ПОЛЬЗОВАТЕЛИ