Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[php] Tegenstrijdige foutmelding

Pagina: 1
Acties:

Onderwerpen


  • telefoontoestel
  • Registratie: Oktober 2002
  • Laatst online: 29-06-2024

telefoontoestel

Maak me gelukkig....Bel!!

Topicstarter
Ik zit met een functie die uit een tekst bestand een soort van register laad. Om te controleren vraag ik dan een array index op die de versie nummer bevat, maar dan krijg ik steevast de melding dat de index niet bestaat. Als ik daarentegen vlak daarvoor die zelfde index op het scherm laat weergeven krijg ik gewoon de waarde te zien en ook komt die terug als ik print_r gebruik. Wat kan er fout gaan? Ik heb van alles geprobeerd en ook de functie opnieuw geschreven, maar toch weer dezelfde fout.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    private function interpret($file){
        $current_root_key = "registry";
        foreach($file as $line){
            $line = trim($line);
            if($line == "") continue;
            
            if(preg_match("~^;~", $line)) continue;
            if(preg_match("~^\[([a-z0-9]){1,256}\]~i", $line)){
                $line = strtolower($line);
                $line = str_replace("[", "", $line);
                $line = str_replace("]", "", $line);
                $current_root_key = $line;
                continue;
            }
            else {
                if(!preg_match("~=~", $line)) continue; // no = parameter
                $parts = explode("=", $line);
                $class_key = strtolower(array_shift($parts));
                count($parts) > 1 ? $value = unserialize(implode("=", $parts)) : $value = unserialize($parts[0]);
                $this->registry[$current_root_key][$class_key] = $value;
            }
        }


en zo ziet het voorbeeld register bestand er uit

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
;PHP5 Solutions Registry File
[REGISTRY]
Version=d:0.1000000000000000055511151231257827021181583404541015625;
[PATHS]
base_path=s:3:"../";
www_path=s:7:"../www/";
controller_path=s:15:"../controllers/";
viewer_path=s:11:"../viewers/";
model_path=s:10:"../models/";
application_path=s:16:"../applications/";
user_path=s:9:"../users/";
languages=s:13:"../languages/";
[SETTINGS]
language=s:5:"nl-nl";
[PROGRAMS]

telefoontoestel


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 20-11 11:59

NMe

Quia Ego Sic Dico.

En nu moeten wij raden op welke regel het fout gaat, wat je daar probeert af te drukken en wat je array daadwerkelijk bevat? Je hebt vooralsnog alleen je code gedumpt en geroepen "het werkt niet!" en inderdaad, dat werkt niet als je geholpen wil worden.

Als ik moet raden (want veel meer kan ik niet zonder je testcase zelf te gaan draaien...) dan gok ik op het feit dat array_shift een element van je array afgooit. Weet je zeker dat je niet de reset-functie nodig hebt?

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • Peter
  • Registratie: Januari 2005
  • Laatst online: 21-11 22:36
Kijk sowieso eens naar parse_ini_file.

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 20-11 11:59

NMe

Quia Ego Sic Dico.

De structuur van die file lijkt redelijk anders dan die van een ini file. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

NMe schreef op zaterdag 12 maart 2011 @ 11:39:
[...]

De structuur van die file lijkt redelijk anders dan die van een ini file. :)
Volgens mij niet, hoor? :P
code:
1
2
3
4
5
6
7
8
9
10
11
; This is a sample configuration file
; Comments start with ';', as in php.ini

[first_section]
one = 1
five = 5
animal = BIRD

[second_section]
path = "/usr/local/bin"
URL = "http://www.example.com/~username"

Ik zie dezelfde structuur er wel in terug. Toegegeven, TS' bestand heeft minder whitespace en puntkomma's aan het eind van de regels, maar verder lijkt het toch aardig overeen te komen.

[ Voor 48% gewijzigd door CodeCaster op 12-03-2011 11:43 ]

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


  • Peter
  • Registratie: Januari 2005
  • Laatst online: 21-11 22:36
NMe schreef op zaterdag 12 maart 2011 @ 11:39:
[...]

De structuur van die file lijkt redelijk anders dan die van een ini file. :)
Dit is gewoon een ini bestand hoor. De values zijn door serialize() gehaald alvorens opgeslagen te worden.

PHP:
1
2
3
4
5
$configurationFile = parse_ini_file ('settings.ini', true, INI_SCANNER_RAW);
array_walk_recursive ($configurationFile, function (&$value, $key)
{
        $value = unserialize ($value);
});


Waarbij "settings.ini" het bestand is als opgegeven in de TS :)

[ Voor 29% gewijzigd door Peter op 12-03-2011 11:53 ]


  • ReenL
  • Registratie: Augustus 2010
  • Laatst online: 14-09-2022
Met deze code gaat het de TS nog steeds niet lukken, zijn parser werkt, maar zijn manier van uitlezen niet. Hij zal de foutmelding, de print_r en het "uitlezen" gedeelte moeten posten voordat we een goed antwoord kunnen geven.

Zie:
krijg ik gewoon de waarde te zien en ook komt die terug als ik print_r gebruik

  • telefoontoestel
  • Registratie: Oktober 2002
  • Laatst online: 29-06-2024

telefoontoestel

Maak me gelukkig....Bel!!

Topicstarter
Ik zat er inderdaad later aan te denken dat ik vergeten ben een voorbeeld te plaatsen, zat toen alleen al in de auto. Als ik bovenstaande code de volgende debug regels zet krijg ik dus ook de vreemde resultaten.

PHP:
1
2
3
4
5
6
7
// private function interpret($file){
// ....
print_r($this->registry);
print "<br />";
print $this->registry["registry"]."<br />";
if(array_key_exists("version", $this->registry["registry"])) print $this->registry["registry"]["version"]."<br />";
// }


Dit resulteerd in de volgende output:
code:
1
2
3
4
5
6
7
8
9
10
Array ( [registry] => Array ( [version] => 0.1 ) [paths] => Array ( [base_path] => ../ [www_path] => ../www/ [controller_path] => ../controllers/ [viewer_path] => ../viewers/ [model_path] => ../models/ [application_path] => ../applications/ [user_path] => ../users/ [languages] => ../languages/ ) [settings] => Array ( [language] => nl-nl ) ) 
Array
0.1
Notice: Undefined index: registry in C:\Program Files\Server\Files\kernel\class.registry.php5 on line 176


Notice: Undefined index: registry in C:\Program Files\Server\Files\kernel\class.registry.php5 on line 177

Warning: array_key_exists() expects parameter 2 to be array, null given in C:\Program Files\Server\Files\kernel\class.registry.php5 on line 177
Registry not loaded or incompatible with current Registry( 2000)

De waardes worden dus wel weergegeven, maar vervolgens leveren diezelfde waardes ook de errors op die eronder staan. Bestaan ze dan wel (de waarde wordt weergegeven) of niet (de errors).

telefoontoestel


  • Peter
  • Registratie: Januari 2005
  • Laatst online: 21-11 22:36
De errors worden door andere code (of een tweede uitvoer) weergegeven, anders stonden ze in een andere volgorde. Weet je zeker dat de regels overeen komen? Gebruik ook eens var_dump in plaats van print_r, die laat net iets meer informatie zien.

  • telefoontoestel
  • Registratie: Oktober 2002
  • Laatst online: 29-06-2024

telefoontoestel

Maak me gelukkig....Bel!!

Topicstarter
Met var_dump kwam ik ook niet verder. Het lijkt wel of het ergens blijft hangen en na de __destruct wordt aangeroepen. Ik had ook dergelijke problemen met fopen en exceptions in de __destruct functie. Na veel zoekwerk kwam ik erachter dat bepaalde handelingen niet (meer) toegelaten lijken te zijn in die functie doordat de php engine de boel al aan het opruimen is voordat het feest is afgelopen.

Ik heb de betreffende functies nu herschreven met de parse_ini_file functie (bedankt voor de tip, kende de functie nog niet) en de destruct heb ik leeg gemaakt. Nu lijken alle problemen vooralsnog verholpen en doet ie wat hij hoort te doen. Het vereist alleen wel het aanroepen van een cleanup functie.

telefoontoestel


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Het vereist alleen wel het aanroepen van een cleanup functie.
Waarom? Het nut van destructors in PHP ontgaat me een beetje, laat staan dat het een vereiste is. Ik ben wel benieuwd waarom je dat denkt cq vindt.

Overigens kan ik me slecht voorstellen dat een rechtgeaarde programmeur zich erbij neerlegt dat zo'n wazig probleem zomaar kan bestaan. Daar moet toch een verklaring voor zijn? Of is dit pure projectie van me? ;)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 20-11 11:59

NMe

Quia Ego Sic Dico.

drm schreef op zondag 13 maart 2011 @ 01:19:
[...]

Overigens kan ik me slecht voorstellen dat een rechtgeaarde programmeur zich erbij neerlegt dat zo'n wazig probleem zomaar kan bestaan.
Eens, al denk ik dat Peter gelijk heeft en het gewoon een tweede call is die mis gaat. Zie ook de "Array" op regel twee.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • telefoontoestel
  • Registratie: Oktober 2002
  • Laatst online: 29-06-2024

telefoontoestel

Maak me gelukkig....Bel!!

Topicstarter
Dat leek mij ook, dat is dus zo vreemd. Nu ik de functie heb herschreven met bovengenoemde aanpassingen kan ik de fout dus ook niet meer reproduceren.

Wat betreft de destructors. Bij aanpassingen tijdens runtime moeten deze worden opgeslagen. Dit doe ik dan het liefst op het eind, maar er is geen mogelijkheid om dit in de destruct functie te doen middels fopen (of database connecties). Er moet dus voor het eindigen van het script een extra cleanup functie aangeroepen worden om de gegevens op te slaan.

telefoontoestel


  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Ik kan me voorstellen, maar ik kan daar even geen onderbouwing voor vinden dus het is een 'gut feeling', dat het persisten van je data in een destructor geen goed idee is. Wat doe je bijvoorbeeld als je databaseverbinding al is gesloten op het moment dat je wil opslaan, of wat doe je met fouten die op dat moment optreden?

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


  • Peter
  • Registratie: Januari 2005
  • Laatst online: 21-11 22:36
De volgorde van de __destruct aanroepingen in PHP is niet volledig te voorspellen. Het kan dus prima zijn dat bepaalde afhankelijkheden al weg zijn, terwijl een andere destructor deze nog wel nodig heeft, precies wat CodeCaster zegt dus.

Je kunt een work-around implementeren door een register_shutdown_function te registreren en van daaruit verschillende classes af te sluiten, mogelijk door calls naar unset() (en dus expliciet __destruct aanroepen), mogelijk door je eigen methode te implementeren.

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

De destructor wordt door de garbage collector aangeroepen, dus zelfs als je een unset doet (waarmee je de refcount alleen maar verlaagt) kun je er niet zeker van zijn dat de destructor op dat moment aangeroepen wordt. Het is sowieso bad practice om logica in je destructor te stoppen. Het enige waar een destructor goed voor is is resources opruimen die niet meer nodig zijn als het object niet meer gebruikt wordt, maar aangezien PHP dat al voor je doet aan het eind van de request lifecycle, kun je de destructors net zo goed niet implementeren, vandaar mijn opmerking dat het nut van destructors me een beetje ontgaat in PHP.

Waar je eventueel naar zou kunnen kijken is register_shutdown_function(), maar mijn persoonlijke mening is dat je magic zoveel mogelijk moet killen, en je code er veel duidelijker van wordt als je alles gewoon expliciet maakt.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 20-11 11:59

NMe

Quia Ego Sic Dico.

Persistentie hoort in een method genaamd Store, cleanup code hoort in een destructor, simple as that. 100% eens met drm, CodeCaster en Peter dus, haal die persistentie eens gauw weg uit je destructorcode.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.

Pagina: 1