[php] Recursive dependency error

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • JeRa
  • Registratie: Juni 2003
  • Laatst online: 30-04 10:28

JeRa

Authentic

Topicstarter
Ik wilde een simpel node-systeem gaan maken, waarbij ik met een 'parent' en een array van 'children' werk. Nu liep ik daar halverwege op vast, vanwege een recursive dependency error (een node heeft een verwijzing naar zijn children, die op hun beurt weer een verwijzing hebben naar die node).

Een voorbeeld waarbij dit optreedt:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
class node {
    var $verwijzing;
}

$object1 = new node();
$object2 = new node();

$object1->verwijzing = &$object2;
$object2->verwijzing = &$object1;

if ($object1 == $object2)
    echo "\$object1 == \$object2";


Dit zal vastlopen met het volgende bericht:

Fatal error: Nesting level too deep - recursive dependency?

En dit op regel 13, de vergelijking dus. Hoe kan ik de node objects vergelijken zonder dat dit probleem optreedt? Doe ik iets fout m.b.t. mijn opzet?

ifconfig eth0 down


Acties:
  • 0 Henk 'm!

  • RedRose
  • Registratie: Juni 2001
  • Niet online

RedRose

Icebear

Je hebt nergens je base case gedefinieerd: dus wanneer de functie zou moeten ophouden met werken en niet eindeloos doorgaat met zichzelf aanroepen. :)

edit: dacht ik. :+

[ Voor 11% gewijzigd door RedRose op 03-02-2004 16:01 ]

Sundown Circus


Acties:
  • 0 Henk 'm!

  • kvdveer
  • Registratie: November 2000
  • Laatst online: 07-11-2023

kvdveer

Z.O.Z.

Wat is je php versie?
In php5 kan ik het iig reproduceren:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[kvdveer@localhost] ~ > php -v
PHP 5.0.0b1 (cgi) (built: Sep  2 2003 12:09:28)
Copyright (c) 1997-2003 The PHP Group
Zend Engine v2.0.0-dev, Copyright (c) 1998-2003 Zend Technologies

[kvdveer@localhost] ~ > php
<?
class node {
    var $verwijzing;
}

$object1 = new node();
$object2 = new node();

$object1->verwijzing = &$object2;
$object2->verwijzing = &$object1;

if ($object1 == $object2)
    echo "\$object1 == \$object2";
?>
Content-type: text/html
X-Powered-By: PHP/5.0.0b1

Fatal error:  Nesting level too deep - recursive dependency? on line 12


Het probleem is blijkbaar dat PHP de inhoud van het object vergelijkt - niet de referentie... en ook nog eens zonder early faliour...

Je kunt forceren de referentie te vergelijken met ===

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?
class node {
    var $verwijzing;
}

$object1 = new node();
$object2 = new node();

$object1->verwijzing = &$object2;
$object2->verwijzing = &$object1;

if ($object1 === $object2)
    echo "\$object1 == \$object2";
?>


Het probleem is dan dat `$object1 == new node()` false oplevert.

[ Voor 33% gewijzigd door kvdveer op 03-02-2004 16:14 ]

Localhost, sweet localhost


Acties:
  • 0 Henk 'm!

Verwijderd

zelf een .equals schrijven ofzo, waarmee je het met een ander object kunt vergelijken

Acties:
  • 0 Henk 'm!

  • RedRose
  • Registratie: Juni 2001
  • Niet online

RedRose

Icebear

kvdveer schreef op 03 februari 2004 @ 16:10:
Wat is je php versie?
In php5 kan ik het iig reproduceren:
Ik in PHP 4 ook. Het enige dat ik kan verzinnen is dat er met deze code constant nieuwe nodes aangemaakt worden.

Sundown Circus


Acties:
  • 0 Henk 'm!

  • kvdveer
  • Registratie: November 2000
  • Laatst online: 07-11-2023

kvdveer

Z.O.Z.

Na wat delibereren met collega's:

Het is logisch dat je die foutmelding krijgt, in achtgenomen hoe PHP die objecten vergelijkt.
Hij vergelijkt namelijk de verwijzing. Beide objecten hebben die verwijzing. Er zijn geen andere zaken om te vergelijken dus wordt de inhoud van de verwijzingen vergeleken. Die lijken overeen te komen (beide verwijzingen bestaan slechts uit een verwijzing), dus wordt de inhoud van die verwijzing vergeleken. Die lijken overeen te komen (beide verwijzingen bestaan slechts uit een verwijzing), dus wordt de inhoud van die verwijzing vergeleken. Die lijken overeen te komen (beide verwijzingen bestaan slechts uit een verwijzing), dus wordt de inhoud van die verwijzing vergeleken. Die lijken overeen te komen (beide verwijzingen bestaan slechts uit een verwijzing), dus wordt de inhoud van die verwijzing vergeleken. enz. enz. (leuk, CTRL-v :))
Zoals ik eerder al zij - de reference vergelijken is zeer eenvoudig, het object zelf vergelijken is een digitale hel.

[ Voor 34% gewijzigd door kvdveer op 03-02-2004 17:09 ]

Localhost, sweet localhost


Acties:
  • 0 Henk 'm!

  • JeRa
  • Registratie: Juni 2003
  • Laatst online: 30-04 10:28

JeRa

Authentic

Topicstarter
Ik gebruik PHP 4.3.4, voor alle duidelijkheid :)
kvdveer schreef op 03 februari 2004 @ 17:08:
Zoals ik eerder al zij - de reference vergelijken is zeer eenvoudig, het object zelf vergelijken is een digitale hel.
Ik ben pointers gewend, en die zijn zeer eenvoudig te vergelijken; je controleert immers alleen of ze naar hetzelfde adres verwijzen. Maar een 'reference' in PHP werkt kennelijk anders, zo wordt de inhoud van het object waarnaar de reference verwijst ook vergeleken om te controleren of de twee objecten gelijk zijn.

Een eigen vergelijking schrijven kan niet, omdat ik zeker wil weten of de objecten ook daadwerkelijk exact hetzelfde zijn (geen kopie, maar bijvoorbeeld twee references die naar hetzelfde object verwijzen). Ik stuitte op dit probleem tijdens het maken van een node-systeem waarin ik een bepaald object terug kreeg waarvan ik niet wist of het een kopie was of een reference naar het originele object.

ifconfig eth0 down


Acties:
  • 0 Henk 'm!

  • stekkel
  • Registratie: Augustus 2001
  • Laatst online: 17-09 08:05
lijkt me logisch dat het niet werkt, je hebt een kringverwijzing en dat is lastig vergelijken als php de inhoud van de objecten wil gaan vergelijken en daarbij de references gaat volgen.

Acties:
  • 0 Henk 'm!

Verwijderd

JeRa schreef op 03 februari 2004 @ 17:29:
Een eigen vergelijking schrijven kan niet, omdat ik zeker wil weten of de objecten ook daadwerkelijk exact hetzelfde zijn (geen kopie, maar bijvoorbeeld twee references die naar hetzelfde object verwijzen).
Waarom niet?

Niet echt een mooie oplossing, maar gewoon een eigen functie schrijven, die een nieuwe member variable in het eerste te testen object aanmaakt. Is deze vervolgens in het 2e object aanwezig, dan weet je genoeg. Tot slot uiteraard de member variabele weer weghalen.

http://www.digiways.com/articles/php/smartcompare/

Acties:
  • 0 Henk 'm!

  • JeRa
  • Registratie: Juni 2003
  • Laatst online: 30-04 10:28

JeRa

Authentic

Topicstarter
Verwijderd schreef op 04 februari 2004 @ 02:20:
[...]

Niet echt een mooie oplossing, maar gewoon een eigen functie schrijven, die een nieuwe member variable in het eerste te testen object aanmaakt. Is deze vervolgens in het 2e object aanwezig, dan weet je genoeg. Tot slot uiteraard de member variabele weer weghalen.
Ik vind de oplossing mooi genoeg om te gebruiken :)

Ik dacht dat ik zelf geen vergelijking kon schrijven, omdat ik dan alleen de inhoud van de objecten zou gaan vergelijken. Dit is echter een veel slimmere manier, dank hiervoor ;)

ifconfig eth0 down


Acties:
  • 0 Henk 'm!

Verwijderd

JeRa schreef op 04 februari 2004 @ 10:37:
[...]

Ik vind de oplossing mooi genoeg om te gebruiken :)
Tjah om zomaar een member variabele te introduceren is niet echt netjes, maar aangezien je hem toch meteen weer verwijdert en gezien het feit dat het anders erg lastig zou gaan worden, is het niet echt een slechte oplossing ;)
Ik dacht dat ik zelf geen vergelijking kon schrijven, omdat ik dan alleen de inhoud van de objecten zou gaan vergelijken. Dit is echter een veel slimmere manier, dank hiervoor ;)
Ur welcome :)
Pagina: 1