Нядаўна сутыкнуўся з неабходнасцю пераносу некалькіх сайтаў майго знаёмага на выдзелены сервер, сайты пабудаваны на аснове рухавічка DLE (Data Life Engine) версій 8.3 і 9.3. Скапіяваў ўсе файлы сайтаў, выставіў правільныя правы для чытання і запісы на неабходныя папкі і заліў дампы баз дадзеных - пасля гэтага сайты зарабілі ды вось толькі не зусім карэктна ... На сайтах зніклі загалоўкі, у некаторых блоках тэкст, у адмінку пры праглядзе спісу публікацый няма загалоўкаў навін, пошук публікацый па карыстачу прыводзіць да пусты белай старонцы, праблемы з аўтарызацыяй праз форму на сайце. Стаяў выбар: даунгрейд PHP да версіі 5.2 або праўка рухавічкоў пад PHP 5.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 ().
- Для працы нам будзе патрэбны Total Commander і Notepad ++.
- Загружаем з сайта сабе на лакальны кампутар тэчку engine (калі на сайце ёсць іншыя тэчкі са скрыптамі, напрыклад forum, то трэба іх таксама скапіяваць для будучай праўкі); Робім копію архіва з загружанымі файламі ў надзейнае месца на ўсялякі выпадак, калі трэба будзе нешта вярнуць назад. Распакоўваецца яшчэ адну копію файлаў (яны ў нас будуць працоўнымі) у любую зручную тэчку, напрыклад d: Work.
- Адкрываем тэчку з загружанымі скрыптамі ў Total Commander'е і ціснем ALT + F7 (пошук), там дзе "шукаць файлы" ставім *, а там дзе "З тэкстам" ставім галачку і ўводзім "session_register (" і націскаем Пошук;
- Па завяршэнні пошуку знізу ў панэлі будуць адлюстраваныя знойдзеныя файлы, націскаем кнопачку "Файлы на панэль" - у панэлі Total Commander адлюструецца спіс з знойдзенымі файламі, вылучаем іх правай кнопкай Мішы і перацягваць у Notepad ++.
- Кожны файл адлюстраваны ў сваёй ўкладцы, у кожным файле шукаем выклік функцыі 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?