Nette v PHP 5.3
- fiso
- Člen | 32
Ahoj,
nainštaloval som si najnovšie PHP 5.3–200807131230 a hodilo mi to pár chýb (ja viem že to nie je finálne 5.3, ale myslím, že stojí za to sa na to pozrieť).
Zdá sa, že sa novému phpčku nepáči protected pri magických funkciách (__get, __set, …), treba to prepísať na public.
Pri parse_ini_file sa mu nepáči, že sa používajú špeciálne znaky ako > alebo :, takže sa nedajú používať konfiguračné súbory. V starších verziách to pochopiteľne išlo. Možno by stálo za to, aby sa konktaktovali tvorcovia, nech s tým parse_ini_file moc nevymýšľajú.
Prípadné ďalšie chyby čo nájdem sem pridám.
- fiso
- Člen | 32
Tohto som sa bál:
http://bugs.php.net/bug.php?…
V changelogu:
- Fixed bug #42069 (parse_ini_file() allows using some non-alpha numeric
characters). (Jani)
Vyzerá to tak že túto „feature“ považujú za bug. Jediné rozumné riešenie je asi vlastný parser na INI súbory.
- David Grudl
- Nette Core | 8218
Máš recht, ale dokud se nebude blížit ostrá verze, je zbytečné na momentální nálady tvůrců reagovat.
- fiso
- Člen | 32
Nie som si celkom istý či opravenie bugu je možné označiť ako momentálnu náladu tvorcov PHP, uvidíme. Každopádne som potreboval spojazdniť INI súbory, takže tu je taký malý návod ako na to:
V triede ConfigAdapterIni (nette/Config/ConfigAdapterIni.php) v metóde load treba zameniť parse_ini_file za nasledovné volanie
$data = self::parseIniFile($file);
Potom treba doplniť do triedy túto metódu:
/**
* PHP implementation of parse_ini_file function
* @param string
* @return array
*/
private static function parseIniFile($file)
{
$ini = file($file);
// file has no contents
if(count($ini) == 0) {
return array();
}
$section = "";
$result = array();
$i = 0;
foreach ($ini as $line) {
$line = trim($line);
$line = str_replace("\t", " ", $line);
// Line comments
if(preg_match('/^\s*;.*/', $line) || !$line) {
continue;
}
// Sections
if ($line{0} == '[') {
$section = substr($line, 1, -1);
$result[$section] = array();
continue;
}
// Key-value pair
list($key, $value) = explode('=', $line, 2);
$key = trim($key);
$value = trim($value);
// Value parsing
if($value{0} != '"' && $value{0} != "'") { // constant
// trim comment, if any
if(($pos = strpos($value, ";")) !== FALSE) {
$value = substr($value, 0, $pos);
}
$value = defined($value) ? constant($value) : $value;
} else { // string
$escaping = 0;
$broken = false;
for($a = 1, $len = strlen($value); $a < $len; $a++) {
if($value{$a} == "\\") {
$escaping++;
} elseif($escaping % 2 == 0) {
$escaping = 0;
}
// terminate parsing
if($value{$a} == "'" || $value{$a} == '"' && $escaping == 0) {
$value = substr($value, 1, $a-1);
$broken = true;
break;
}
}
if(!$broken) {
$value = substr($value, 1);
}
}
if($section) {
$result[$section][$key] = $value;
} else {
$result[$key] = $value;
}
}
return $result;
}
Trochu okukané z http://sk.php.net/…ini-file.php a upravené, nie príliš otestované ale funguje fajn.
- David Grudl
- Nette Core | 8218
Pomohlo by použít jiný oddělovač
ConfigAdapterIni::$keySeparator
a to -
. Parser v PHP
5.3 přežije ještě znaky _
a .
, ale pokud chceš
přes konfigurák nastavovat PHP direktivy způsobem
set> date.timezone = "Europe/Prague"
set> iconv.internal_encoding = "%encoding%"
zbývá skutečně jen pomlčka. Takže asi takto:
set-date.timezone = "Europe/Prague"
set-iconv.internal_encoding = "%encoding%"
Pokud se parser v PHP 5.3 nezmění, asi přidám podporu pro podsekce, nějak takto:
[common.variable]
tempDir = %appDir%/cache
foo = %bar% world
bar = hello
[common.set]
date.timezone = "Europe/Prague"
iconv.internal_encoding = "%encoding%"