Рішення проблем сумісності в DLE після поновлення до PHP 5.4

  1. Передмова
  2. Шукаємо суть проблеми
  3. Приступаємо до виправлень
  4. На завершення

Нещодавно зіткнувся з необхідністю перенесення кількох сайтів мого знайомого на виділений сервер, сайти побудовані на основі движка DLE (Data Life Engine) версій 8 Нещодавно зіткнувся з необхідністю перенесення кількох сайтів мого знайомого на виділений сервер, сайти побудовані на основі движка DLE (Data Life Engine) версій 8.3 та 9.3. Скопіював всі файли сайтів, виставив потрібні права для читання і запису на необхідні папки і залив дампи баз даних - після цього сайти заробили та ось тільки не зовсім коректно ... На сайтах пропали заголовки, в деяких блоках текст, в адмінці при перегляді списку публікацій немає заголовків новин, пошук публікацій з користувачу призводить до порожній білій сторінці, проблеми з авторизацією через форму на сайті. Стояв вибір: даунгрейд PHP до версії 5.2 або правка движків під PHP 5.4 - я вибрав останній, здавалося-б божевільний варіант ...

зміст:

  1. Передмова
  2. Шукаємо суть проблеми
  3. Приступаємо до виправлень
  4. На завершення

Передмова

Для початку вирішив пошукати що народ думає і як надходить в даній ситуації, кинувся в пошук і навідкривали різних форумів, сервісів питань-відповідей. Всі поради і коментарі зводилися до кількох рішень: даунгрейд PHP, оновлення ДЛЕ до найновішої версії (там все коректно працює з PHP 5.4), змінити хостера)))

Загалом я зрозумів що потрібно брати і розбиратися самому, оскільки ниодного тлумачного ради я не зустрів - я вибрав шлях який йде врозріз з усіма порадами і підказками на форумах і конференціях.

(i) Якщо вам не цікаві технічні нюанси і потрібно тільки керівництво до дії то можете відразу переходити до нижньої частини статті.

Отже, для початку розберемося що ж змінилося в PHP 5.4 без зворотної сумісності, для цього в кілька кліків через Гугл потрапляємо ось сюди: Що змінилося в PHP 5.4.x? , А там йдемо по посиланню кілька несовместимостей .

Шукаємо суть проблеми

Ось основні незворотні зміни які нам цікаві:

  • Безпечного режиму в PHP більше немає (для ДЛЕ це не критично, тут все ОК)
  • "Чарівні" лапки (Magic Quotes) тепер не працюють (тут бажано буде перевірити)
  • Можливість передачі за посиланням під час виклику функції була прибрана (теж може щось поламати, перевіримо)
  • Оператори break і continue тепер не приймають аргументів у вигляді змінної (рідко зустрічав таке в ДЛЕ, думаю тут все ОК)
  • Якщо ви використовуєте функцію htmlentities з азіатськими наборами символів, то вона працює також, як функція htmlspecialchars. (Потрібно буде перевірити)
  • Вилучені некториє функції, нам цікаві тут: session_is_registered (), session_register () і session_unregister ().

За замовчуванням в DLE включено достатню відображення помилок, що нам дуже до речі для відстеження проблемних скриптів:

@error_reporting (E_ALL ^ ​​E_WARNING ^ E_NOTICE); @ini_set ( 'display_errors', true);

Дивимося проблемні сторінки на предмет виведення повідомлень про помилку - відразу ж натрапив на помилку:

Function set_magic_quotes_runtime () is deprecated

На сайтах коштують модулі SAPE і матюкається саме на файл-скрипт sape.php. Функції set_magic_quotes_runtime вже немає починаючи з PHP 5.3, просто потрібно видалити всі виклики цієї функції з файлу і все буде в порядку. Щодо поновлення коду SAPE з сайту партнерки я паритися не став, все посилання відображаються коректно.

Тепер нам потрібно визначити через що не відображаються заголовки новин, наприклад в адмінці, для цього відстежуємо файл який відповідає за виведення модуля і шукаємо функцію або рядок яка відповідає за підготовку / висновок назви новини.

Після недовгих пошуків за кодом було знайдено що текст заголовка перед виведенням екранується (фільтрується) функцією htmlspecialchars - ця функція потрібна для перетворення спеціальних HTML символів в безпечні для виведення користувачеві в браузер.

Прибравши фільтрацію цією функцією все назви статей в адмінці повернулися на своє місце. Функція htmlspecialchars використовується досить часто і відмовитися від її використання дуже нерозумне рішення, потрібно розібратися чому вона не працює.

Дослідивши як в DLE в різних модулях викликається дана функція я прийшов до висновку що викликають її дуже часто з одним аргументом, а іноді ще в якості іншого аргументу передається прапор ENT_QUOTES.

Звернувшись до документації по PHP уважно розглянемо які аргументи приймає функція:

string htmlspecialchars (string $ string [, int $ flags = ENT_COMPAT | ENT_HTML401 [, string $ encoding = 'UTF-8' [, bool $ double_encode = true]]])

Отже 1й аргумент - рядок для обробки, 2й - спеціальний прапор для вказівки необхідної обробки, 3й - кодування, 4й - перемикач що вказує чи потрібно перетворювати існуючі html-суті.

Отже, прапори за замовчуванням використовуються ENT_COMPAT | ENT_HTML401, кодування за замовчуванням UTF-8, наступний аргумент ... стоп, стоп ... кодування за замовчуванням UTF-8? - так у мене ж сайти в CP1251, я вирішив спробувати примусово вказати функції htmlspecialchars кодування cp1251 і що ви думаєте, назви новин стали відображатися правильно.

Вирішив я погуглити щодо даної теми і з'ясувалося що функція htmlspecialchars в PHP 5.4 коректно працює з кодуваннями UTF-8 CP1251 якщо в якості кодування примусово передати порожній рядок, ось як:

$ Title = htmlspecialchars ($ str, ENT_COMPAT, ''); $ Title = htmlspecialchars ($ str, ENT_QUOTES, '')

Поправивши всі функції в движку з текстами все стало ОК.

Навіть після виправлення всіх функцій htmlspecialchars все ж в деяких модулях тексти можуть відображатися в невірної кодуванні. Причиною цього може бути функція htmlentities яка переводить символи HTMl по суті. Виклик її в скриптах здійснюється таким же чином як і htmlspecialchars, тому слід так само пройтися по всіх скриптів де є ця функція і виправити її виклик.

Залишилося розібратися з порожньою сторінкою при виведенні списку новин по імені користувача.

Відшукавши модуль що відповідає за відображення цієї сторінки я почав дивитися на ніж затикається виконання скрипта. Ставимо по порядку в різних місцях скрипта висновок отладочного тексту і дивимося на якій ділянці скрипта припиняється висновок налагодження. Ось оцінний код для вставок - простий echo, тут нічого вигадувати:

echo 'Testing 1';

Зупинка може відбуватися через включення в скрипт іншого скрипта, значить і його таким самим методом потрібно прищепити до з'ясування остаточної непрацюючої точки.

Таким способом було з'ясовано що до затикаючи призводить функція session_register () в одному з модулів що відповідає за авторизацію. Після виклику даної функції не започатковано змінні в глобальному масиві $ _SESSION. Маючи досвід роботи з сесіями я без побоювання закоментувавши функції session_register () і проблема з порожньою сторінкою зникла - все відображається як потрібно, з авторизацією немає проблем.

Можна звичайно відразу ж зробити пошук по всіх скриптів на наявність в них функції session_register і поудалять її там де вона є, але мені хотілося рассказатьь тобі, мій читач, як ще можна виловити подібний баг.

Були також перевірені і інші несумісності PHP 5.4 на предмет наявності в скриптах сайтів на DLE - більше нічого правити не знадобилося.

Підіб'ємо підсумок, підгонка старого движка DLE для роботи з PHP 5.4 полягає ось у чому:

  • виправлення виклику функцій htmlspecialchars ().
  • виправлення виклику функцій htmlentities ().
  • видалення / коментування викликів функції session_register ().

Приступаємо до виправлень

Розповім детально як досить швидко і зручно поправити скрипти движка будь-якої версії.

Чистка функції session_register ().

  1. Для роботи нам буде потрібен Total Commander і Notepad ++.
  2. Завантажуємо з сайту собі на локальний комп'ютер папку engine (якщо на сайті є інші папки зі скриптами, наприклад forum, то потрібно їх також скопіювати для майбутньої правки); Робимо копію архіву із завантаженими файлами в надійне місце на всякий випадок, якщо потрібно буде щось повернути назад. Розпаковуємо ще одну копію файлів (вони у нас будуть робочими) в будь-яку зручну папку, наприклад d: Work.
  3. Відкриваємо папку з завантаженими скриптами в Total Commander'е і тиснемо ALT + F7 (пошук), там де "шукати файли" ставимо *, а там де "З текстом" ставимо галочку і вводимо "session_register (" і натискаємо Пошук;
  4. По завершенню пошуку знизу в панелі будуть відображені знайдені файли, натискаємо кнопочку "Файли на панель" - в панелі Total Commander відобразиться список зі знайденими файлами, виділяємо їх правою кнопкою мишки і перетягуємо в Notepad ++.
  5. Кожен файл відображений у своїй вкладці, в кожному файлі шукаємо виклик функції session_register з будь-якими аргументами і повністю її видаляємо. Для зручного пошуку тиснемо CTRL + F і панель пошуку перемістимо вправо до краю не закриваючи її, вводимо туди session_register і чистимо всі знайдені файли від цієї функції.

Для більшої ясності викладеного приведу кілька скріншотів процесу:

Мал. 1. Пошук тексту в в папці за допомогою Total Commander.

Мал. 2. Позначаємо файли для редагування в Total Commander.

Мал. 3. Пошук коду та його редагування в Notepad ++ (клікніть для збільшення).

Виправлення функції htmlspecialchars.

Тут ництва буде побільше. Так само по аналогії шукаємо всі файли скриптів, в яких зустрічається ф-я htmlspecialchars, таких файлів може знайтися порядку 40-70 штук (залежно від кількості встановлених плагінів і модулів до движку), перетягуємо їх в наш улюблений Notepad ++ і виробляємо правки в залежності від того як викликається ф-я, це дуже важливо!

а) Якщо функція викликається з одним аргументом, наприклад:

$ Title = htmlspecialchars ($ title)
$ Name = $ db-> safesql ($ parse-> process (htmlspecialchars (trim ($ _POST [ 'name']))));

то додаємо ще два аргументи, правимо її до Слуда увазі:

$ Title = htmlspecialchars ($ title, ENT_COMPAT, '')
$ Name = $ db-> safesql ($ parse-> process (htmlspecialchars (trim ($ _POST [ 'name']), ENT_COMPAT, '')));

б) Якщо функція викликається з двома аргументами, наприклад в fullsearch.php:

$ Tpl-> set ( '{result-author}', "<a href="mailto:".htmlspecialchars($row['gast_email'], ENT_QUOTES)."">"

то додаємо третій - порожній рядок, лапки:

$ Tpl-> set ( '{result-author}', "<a href="mailto:".htmlspecialchars($row['gast_email'], ENT_QUOTES,'')."">"

в) Є моменти (таких небагато, 1-2 шт приблизно) де не потрібно нічого чіпати, наприклад це файли editnews.php, registration.php:

$ Name = $ db-> safesql (trim (htmlspecialchars ($ parse-> process (convert_unicode ($ _ POST [ 'name'], $ config [ 'charset'])))));

Тут змінна $ _POST [ 'name'] наводиться до належним кодуванням за допомогою функції convert_unicode в яку вказано кодування для попередньої конвертації з системної змінної $ config.

Потрібно дуже уважно виправляти всі функції, дивитися вкладеність і де який аргумент. Notepad ++ вміє підсвічувати синтаксис - користуйтеся цим, ставши на одну з лапок функції редактор підсвітить ту лапку, яка закриває першу, ось як приклад з вкладеними функціями:

$ db-> safesql (htmlspecialchars (trim ($ _ POST [ 'name'])));

тут зрозуміло що перед підсвічується лапками потрібно додати два аргументи виходячи з наданих вище варіантів.

Аналогічним способом шукаємо і виправляємо всі виклики функції htmlentities, їх буде набагато меньце - як правило кілька штук.

Після всіх правок закриваємо редактор, пакуємо папки зі скриптами в архів і закачуємо його на хостинг, там розпаковуємо архів з заміною файлів і радіємо результату. Бажано все ж перед розпакуванням архіву видалити старі папки зі скриптами, так буде надійніше і ми будемо впевнені що скрипти у нас тепер ті що потрібно.

Якщо якусь правку зробите невірно то дуже скоро вона себе проявить і ви досить швидко зможете її виправити.

Також раджу пройтися по всіх ключових моментах роботи движка і перевірити працездатність - зареєструвати користувача, пройти авторизацію, створити новина, завантажити картинки, зберегти налаштування в адмінці.

Отже включивши свою логіку і використавши прості підручні програмні засоби ми домоглися потрібного результату. Після ось таких порівняно нескладних але множинних операцій працездатність движка DLE, перенесеного на PHP 5.4, буде відновлена. Принаймні інших глюків поки помічено не було)

На завершення

У цій статті я постарався з одного боку торкнутися складних технічних моментів, а з іншого є роз'яснити новачкові як все виправити. Хоча роботи виходить чимало але це все ж дешевше і практичніше ніж робити даунгрейд PHP або сезжать до іншого хостера в якого стоїть старий PHP 5.2.

До того ж в PHP 5.4 є ряд нововведень, які будуть використовуватися в нових двигунах, які ви можливо будете використовувати, та й швидкість роботи нового PHP явно вище ніж у версії 5.2.

Буду радий вислухати ваші думки і коментарі!

5.4.x?
Кодування за замовчуванням UTF-8?