WBB 2.3.6 und PHP 7.0/7.1 (Umbauanleitung) *Update 07.12.2016*

Hallo Freunde,

ich zeige euch heute, wie ihr euer uralt-WBB2.3.6 unter PHP 7 (sowohl 7.0 als auch 7.1) zum Laufen bekommt. 🙂

Zunächst einmal solltet ihr euer Forum an php 5.6 angepasst haben. Eine Anleitung dazu habe ich hier online gestellt: https://blog.kill0rz.com/2015/04/25/wbb-2-3-6-und-php-5-6/
Danach solltet ihr die Anpassungen von MikeHH durchführen, ihr findet sie hier im Anhang: http://www.v-gn.de/wbb/thread.php?postid=129625#post129625
Den darauf folgenden Post bitte ignorieren, das funktioniert ausdrücklich nicht! Darum kümmern wir uns aber…

Wenn das geschafft ist, geht es weiter. Zunächst einmal schauen wir uns die Migrationsanleitungen vom php-Team an: http://php.net/manual/de/migration70.php
Besonders interessant sind folgende Links:

  • Deprecated features in PHP 7.0.x
  • Die PHP 4-Style Konstruktoren (Name der Konstruktormethode = Name der Klasse) werfen jetzt eine Deprecated-Meldung. Mit PHP 5.3 wurde der neue Style bereits eingeführt (Konstruktormethode heiße __construct) und bis einschließlich php 5.6.X parallel weitergeführt. Jetzt wie gesagt die deprecated-Meldung. Man könnte es noch herauszögern, aber wir bügeln die Änderungen gleich drüber.
  • Changed functions
    • Hier schauen wir uns zunächst die Funktion mktime an, die nun keinen 7. Paramter mehr akzeptiert. Wir haben aber in unserer Software keinen einzigen Aufruf dessen.
    • Das gleiche gilt für gmmktime.
    • Unsere geliebte preg_replace()-Funktion akzeptiert jetzt den /e-Modifier gar nicht mehr. Da muss viel geändert werden.
    • Die anderen Geänderte Funktionen haben keine Auswirkungen auf unser WBB.
  • Removed Extensions and SAPIs
    • Die mysql-Erweiterung wurde entfernt. Good thing haben wir die aber schon damals rausgeschmissen 🙂
  • Backward incompatible changes
    • global akzeptiert nur noch einfache Variablen. Da müssen wir etwas machen.
    • Das new-Statement kann keiner Variablen mehr über eine Referenz zugewiesen werden (class C {}; $c =& new C;). Über einen Regex kann man feststellen, wo wir hier etwas ändern müssen: /\& +new/
  • Other Changes
    • Die date.timezone-Warnung wurde entfernt. Defaultwert ist UTC.
      Grundsätzlich erstmal egal, wenn wir unser php ordentlich konfiguriert haben, aber es kann dennoch nicht schaden, folgendes zu tun:

/global.php

Suche:

<?php

<em>Füge darunter ein:</em>

[php]date_default_timezone_set('Europe/Berlin');

Going hot now:

Hier nochmal der Hinweis: Jedes WBB ist einzigartig. Es kann sein, dass durch Hacks oder sonstige Codeänderungen diese Anleitung hier nicht vollständig ist. Das bitte selbst prüfen!
Außerdem natürlich wie immer der Hinweis: Keine Garantie, ist aber trotzdem getestet, wenn dennoch Fehler auffallen, bitte melden, damit die behoben werden können. 😉

Als erstes kümmern wir uns um die global-Geschichte:

/acp/lib/functions.php
Suche:

global $$name, $wbbuserdata;

Ersetze mit:

global ${$name}, $wbbuserdata;

/lcd.php (Ein Hack, also optional)
Suche:

global $$letter

Ersetze mit:

global ${$letter}

Dann beseitigen wir die &new-Fehler. Ich habe diese allerdings nur in Hacks gefunden, sodass es euch wahrscheinlich gar nicht betrifft:

/xy_megashoutbox.php
/gaestebuch.php

Suche (mehrfach):

&new parse

Ersetze mit:

new parse

Danach schauen wir uns die regulären Ausdrücke mit den /e-Modifiern an:

/acp/lib/class_parse.php
Suche:

var $search = array();
var $replace = array();
var $replace2 = array();

Füge darunter ein:

var $search_replace = array();
var $search_replace2 = array();

Suche:

$this->search[] = "/\[list=(&quot;|['\"]?)([^\"']+)\\1](.+)\[\/list((=\\1[^\"']+\\1])|(\]))/esiU";
$this->replace[] = "\$this->formatlist('\\3', '\\2')";
$this->search[] = "/\[list](.+)\[\/list\]/esiU";
$this->replace[] = "\$this->formatlist('\\1')";
$this->search[] = "/\[url=("|['\"]?)([^\"']+)\\1](.+)\[\/url\]/esiU";
$this->replace[] = "\$this->formaturl('\\2','\\3')";
$this->search[] = "/\[url]([^\"\[]+)\[\/url\]/eiU";
$this->replace[] = "\$this->formaturl('\\1')";

Ersetze mit:

$this->search_replace['/\[list=("|[\'"]?)([^"\']+)\1](.+)\[\/list((=\1[^"\']+\1])|(\]))/siU'] = function($matches) { return $this->formatlist($matches[3],$matches[2]);};
$this->search_replace['/\[list](.+)\[\/list\]/siU'] = function($matches) { return $this->formatlist($matches[1]);};
$this->search_replace['/\[url=("|[\'"]?)([^"\']+)\1](.+)\[\/url\]/siU'] = function($matches) { return $this->formaturl($matches[2],$matches[3]);};
$this->search_replace['/\[url]([^"\[]+)\[\/url\]/iU'] = function($matches) { return $this->formaturl($matches[1]);};

Suche:

$this->replace2[] = "'$this->breakChar[list=\\1$this->breakChar\\2$this->breakChar\\1]$this->breakChar'.\$this->stripSlashes('\\3').'$this->breakChar[/list=\\1$this->breakChar\\2$this->breakChar\\1]$this->breakChar'"; 
$this->replace2[] = "'$this->breakChar[list]$this->breakChar'.\$this->stripSlashes('\\1').'$this->breakChar[/list]$this->breakChar'"; 
$this->replace2[] = "'$this->breakChar[url=\\1$this->breakChar'.\$this->insertBreakChar('\\2').'$this->breakChar\\1]$this->breakChar'.\$this->stripSlashes('\\3').'$this->breakChar[/url]$this->breakChar'";
$this->replace2[] = "'$this->breakChar[url]$this->breakChar' . \$this->insertBreakChar('\\1') . '$this->breakChar[/url]$this->breakChar'";

Ersetze mit:

$this->search_replace2['/\[list=(&quot;|[\'"]?)([^"\']+)\1](.+)\[\/list((=\1[^"\']+\1])|(\]))/siU'] = function($matches) { return $this->breakChar.'[list='.$matches[1].$this->breakChar.$matches[2].$this->breakChar.$matches[1].']'.$this->breakChar.$this->stripSlashes($matches[3]).$this->breakChar.'[/list='.$matches[1].$this->breakChar.$matches[2].$this->breakChar.$matches[1].']'.$this->breakChar;};
$this->search_replace2['/\[list](.+)\[\/list\]/siU'] = function($matches) { return $this->breakChar.'[list]'.$this->breakChar.$this->stripSlashes($matches[1]).$this->breakChar.'[/list]'.$this->breakChar;};
$this->search_replace2['/\[url=(&quot;|[\'"]?)([^"\']+)\1](.+)\[\/url\]/siU'] = function($matches) { return $this->breakChar.'[url='.$matches[1].$this->breakChar.$this->insertBreakChar($matches[2]).$this->breakChar.$matches[1].']'.$this->breakChar.$this->stripSlashes($matches[3]).$this->breakChar.'[/url]'.$this->breakChar;};
$this->search_replace2['/\[url]([^"\[]+)\[\/url\]/iU'] = function($matches) { return $this->breakChar.'[url]'.$this->breakChar.$this->insertBreakChar($matches[1]).$this->breakChar.'[/url]'.$this->breakChar;};

Suche:

if ($allowdynimg == 1) $this->imgsearch2 = "/\[img]([^\"]+)\[\/img\]/esiU";
else $this->imgsearch2 = "/\[img]([^\"\?\&]+\.(gif|jpg|jpeg|bmp|png))\[\/img\]/esiU";
$this->imgreplace2 = "'$this->breakChar[img]$this->breakChar' . \$this->insertBreakChar('\\1') . '$this->breakChar[/img]$this->breakChar'";

Ersetze mit:

if ($allowdynimg == 1) $this->imgsearch2 = "/\[img]([^\"]+)\[\/img\]/siU";
else $this->imgsearch2 = "/\[img]([^\"\?\&]+\.(gif|jpg|jpeg|bmp|png))\[\/img\]/siU";
$this->imgreplace2 = function($matches) { return $this->breakChar.'[img]'.$this->breakChar.$this->insertBreakChar($matches[1]).$this->breakChar.'[/img]'.$this->breakChar;};

Suche:

if ($allowbbcode == 1) {
	if ($this->done['bbcode'] != 1) $this->getbbcode(); 
	$post = preg_replace($this->search, $this->replace, $post);
}

Ersetze mit:

if ($allowbbcode == 1) {
	if ($this->done['bbcode'] != 1) $this->getbbcode();
	$post = preg_replace_callback_array($this->search_replace, $post);
	$post = preg_replace($this->search, $this->replace, $post);
}

Suche:

if ($allowbbcode == 1) {
	if ($this->done['bbcode'] != 1) $this->getbbcode(); 
	$post = preg_replace($this->search, $this->replace2, $post);
	if ($allowimages != 0) $post = preg_replace($this->imgsearch2, $this->imgreplace2, $post);
}

Ersetze mit:

if ($allowbbcode == 1) {
	if ($this->done['bbcode'] != 1) $this->getbbcode();
	$post = preg_replace_callback_array($this->search_replace2, $post); 
	$post = preg_replace($this->search, $this->replace2, $post);
	if ($allowimages != 0) $post = preg_replace_callback($this->imgsearch2, $this->imgreplace2, $post);
}

/acp/lib/functions.php
Suche:

preg_replace("%\[url\]".$threadid_pattern."\[/url\]%ieU", "\$catched_threadids[]=\\3;", $message);
preg_replace("%\[url\]".$postid_pattern."\[/url\]%ieU", "\$catched_postids[]=\\3;", $message);

Ersetze mit:

preg_replace_callback("%\[url\]".$threadid_pattern."\[/url\]%iU", function($matches) use (&$catched_threadids) { $catched_threadids[]=$matches[3];}, $message);
preg_replace_callback("%\[url\]".$postid_pattern."\[/url\]%iU", function($matches) use (&$catched_postids) { $catched_postids[]=$matches[3];}, $message);

Suche:

if (count($threadcache)) {
	// insert topics
	$message = preg_replace("%\[url\]".$threadid_pattern."\[/url\]%ieU", "makeLocalLink('\\1',\\3)", $message);
	$message = preg_replace("%\[url\]".$postid_pattern."\[/url\]%ieU", "makeLocalLink('\\1',\\3,1)", $message);
}

Ersetze mit:

if (count($threadcache)) {
	// insert topics
	$message = preg_replace_callback("%\[url\]".$threadid_pattern."\[/url\]%iU", function($matches) { return makeLocalLink($matches[1],$matches[3]);},$message);
	$message = preg_replace_callback("%\[url\]".$postid_pattern."\[/url\]%iU", function($matches) { return makeLocalLink($matches[1],$matches[3],1);}, $message);
}

/acp/lib/class_templateparser.php
Suche:

$code = preg_replace('!<if\((.*)\)>!sieU', '"\".((".$this->stripSlashes(\'\\1\').") "', $code);

Ersetze mit:

$code = preg_replace_callback('!<if\((.*)\)>!siU', function($matches) { return '".(('.$this->stripSlashes($matches[1]).') ';}, $code);

Suche:

$code = preg_replace('!<expression>(.*)</expression>!sieU', '"\".".$this->stripSlashes(\'\\1\').".\""', $code);

Ersetze mit:

$code = preg_replace_callback('!<expression>(.*)</expression>!siU', function($matches) { return '".'.$this->stripSlashes($matches[1]).'."';}, $code);

/acp/lib/class_parsecode.php
Suche:

function doparse($post) {

Ersetze mit:

function doparse($post, $allowsmilies=false, $allowhtml=false, $allowbbcode=false, $allowimages=false) {

Massig Dank dabei an Schrimm, der hier einige Zeit investiert hat! 🙂

Ich habe bei mir noch Reste von der alten MYSQL-Erweiterung gefunden.
Zur Sicherheit können wir nochmal nach Konstanten suchen.

Suche überall nach (insbesondere in /acp/group.php, /acp/lib/admin_functions.php, /acp/lib/functions.php und /acp/style.php):

MYSQL_BOTH

Ersetze mit:

MYSQLI_BOTH

Suche überall nach (insbesondere in /acp/group.php, /acp/lib/admin_functions.php, /acp/lib/functions.php und /acp/style.php):

MYSQL_ASSOC

Ersetze mit:

MYSQLI_ASSOC

Dann fiel mir beim durchsehen auf, dass wir ja tatsächlich noch ereg_replace-Aufrufe im Quelltext haben! :O
Wird gleich mit geändert:

/acp/lib/class_zip.php
Suche:

$date = ereg_replace($regexp, "\\1-\\2-\\3-\\4-\\5-\\6", $date);

Ersetze mit:

$date = preg_replace($regexp, "\\1-\\2-\\3 \\4:\\5:\\6", $date);

/acp/shoutbox.php (Offenbar ein Hack, also optional)
Suche:

$ereza = ereg_replace(",","", $groupwerte);

Ersetze mit:

$ereza = preg_replace("/,/","", $groupwerte);

So, jetzt bauen wir noch schnell die Klassen um. Das WBB wurde auf dem Standard von vor php 5.3.3 geschrieben, der besagt, dass der Konstruktor einer Klasse den Klassennamen trägt. Das heißt, wir müssen jetzt alle Klassenkonstruktoren ändern.

/acp/lib/class_variableimport.php
Suche:

function variableimport($filename) {

Füge darüber ein:

function __construct($filename) {
	$this->variableimport($filename);
}

/acp/lib/class_parse.php
Suche:

function parse($docensor = 0, $wrapwidth = 0, $showimages = 0, $hilight = '', $usecode = 1, $cuturls = 1, $useCaching = 0) {

Füge darüber ein:

function __construct($docensor = 0, $wrapwidth = 0, $showimages = 0, $hilight = '', $usecode = 1, $cuturls = 1, $useCaching = 0) {
	$this->parse($docensor, $wrapwidth, $showimages, $hilight, $usecode, $cuturls, $useCaching);
}

/acp/lib/class_tpl_file.php
Suche:

function tpl($templatepackid = 0, $path = ".") {

Füge darüber ein:

function __construct($templatepackid = 0, $path = ".") {
	$this->tpl($templatepackid, $path);
}

/acp/lib/class_useronline.php
Suche:

function useronline($can_view_ghosts, $buddylist = '') {

Füge darüber ein:

function __construct($can_view_ghosts, $buddylist = '') {
	$this->useronline($can_view_ghosts, $buddylist);
}

/acp/lib/class_query.php
Suche:

function query($query) {

Füge darüber ein:

function __construct($query) {
	$this->query($query);
}

/acp/lib/class_db_mysql.php
Suche:

function db($server, $user, &$password, $database, $phpversion) {

Füge darüber ein:

function __construct($server, $user, &$password, $database, $phpversion) {
	$this->db($server, $user, $password, $database, $phpversion);
}

/acp/lib/class_language.php
Suche:

function language($languagepackid, $path = '.') {

Füge darüber ein:

function __construct($languagepackid, $path = '.') {
	$this->language($languagepackid, $path);
}

/acp/lib/class_parsecode.php
Suche:

function parsecode($usecode = 1) {

Füge darüber ein:

function __construct($usecode = 1) {
	$this->parsecode($usecode);
}

/acp/lib/class_options.php
Suche:

function options($path2lib) {

Füge darüber ein:

function __construct($path2lib) {
	$this->options($path2lib);
}

/acp/lib/class_smtp.php
Suche:

function smtp_socket() {

Füge darüber ein:

function __construct() {
	$this->smtp_socket();
}

/acp/lib/class_onpm.php (Ein Hack, also optional)
Suche:

function onpm(){

Füge darüber ein:

function __construct() {
	$this->onpm();
}

Das dürfte alles gewesen sein. Viel Spaß unter PHP 7 =)
kill0rz

PS: Ein großes Lob an die Community, dass wir das auf die Beine gestellt bekommen haben. Das zeigt eben, dass das WBB2 noch lange nicht tot ist! 🙂

//Update 15.02.2016

Da fehlte noch was 🙂

/thread.php
Suche:

function FlatThread($threadid) {

Füge darüber ein:

function __construct($threadid){
	$this->FlatThread($threadid);
}

Suche:

function ThreadedThread($threadid) {

Füge darüber ein:

function __construct($threadid) {
	$this->ThreadedThread($threadid);
}

//Update 16.02.2016

…und weiter gehts 🙂

/acp/lib/class_headers.php
Suche:

function send($isacp = 0) {

Ersetze mit:

public static function send($isacp = 0) {

/acp/misc.php
Suche:

function menu(&$itemgroupbit1, &$itemgroupbit2, $personalmenu = 1, $markfirst = 0, $hidelast = 0) {

Füge darüber ein:

function __construct(&$itemgroupbit1, &$itemgroupbit2, $personalmenu = 1, $markfirst = 0, $hidelast = 0) {
	$this->menu($itemgroupbit1, $itemgroupbit2, $personalmenu, $markfirst, $hidelast);
}

Habe auch die Konstruktoren korrigiert, da haben sich Copy&Paste-Fehler eingeschlichen. Bitte nachbessern!

//Update 02.03.2016

Die Zeile

$this->search[] = "/\[list=(&quot;|['\"]?)([^\"']+)\\1](.+)\[\/list((=\\1[^\"']+\\1])|(\]))/esiU";

muss auch entfernt werden; oben korrigiert.

Weiterhin: Habe die Zeile

$date = preg_replace($regexp, "\\1-\\2-\\3 \\4:\\5:\\6", $date);

zu

$date = preg_replace($regexp, "\\1-\\2-\\3-\\4-\\5-\\6", $date);

korrigiert.
Schrimm hat dazu sogar noch eine Codeoptimierung rausgehauen:
Suche nach:

$date = date("Y-m-d H:i:s", $date);

$regexp = "([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})";
$date = ereg_replace($regexp, "\\1-\\2-\\3-\\4-\\5-\\6", $date);
$date_array = explode("-", $date);

(hier gff. preg_replace suchen)

Ersetze mit:

$date = date("Y-m-d-H-i-s", $date);
$date_array = explode("-", $date);

//Update 07.12.2016

Es hat sich herausgestellt, dass Escapings in php- und code-Tags entfernt werden. Daher muss noch folgende Anpassung vorgenommen werden:

/acp/lib/class_parsecode.php

Suche:

while (list($varnr, $code) = each($val)) {
$post = str_replace("{" . $this->hash . "_" . $mode . "_" . $varnr . "}", "[" . $mode . "]" .     str_replace("\\\"", "\"", $code) . "[/" . $mode . "]", $post);
}

Ersetze mit:

while (list($varnr, $code) = each($val)) {
$post = str_replace("{" . $this->hash . "_" . $mode . "_" . $varnr . "}", "[" . $mode . "]" .     $code . "[/" . $mode . "]", $post);
}

/acp/lib/class_parse.php

Folgende Zeile auskommentieren (kommt mehrfach vor):

$code = $this->stripSlashes($code);
This entry was posted in Allgemein, Internet, Tutorials, Updated, WBB. Bookmark the permalink.

6 Responses to WBB 2.3.6 und PHP 7.0/7.1 (Umbauanleitung) *Update 07.12.2016*

Schreibe einen Kommentar zu kill0rz Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Bitte löse die Rechnung! * Time limit is exhausted. Please reload CAPTCHA.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.