[oop] niet bestaande class
In navolging van mijn eerdere topic vandaag, ben ik tot de conclusie gekomen dat ik mijn vraag wellicht anders / breder moet stellen.
Stel ik wil een class Foo gebruiken:
$foo = new Foo();
Echter, om een of andere reden kan het bestand wat bij deze class hoort niet geladen worden (bijvoorbeeld omdat het niet bestaat). Kan ik de fout die hieruit volgt dan op de een of andere manier opvangen?
Stel ik wil een class Foo gebruiken:
$foo = new Foo();
Echter, om een of andere reden kan het bestand wat bij deze class hoort niet geladen worden (bijvoorbeeld omdat het niet bestaat). Kan ik de fout die hieruit volgt dan op de een of andere manier opvangen?
Ger, dankjewel. Wat voor error wordt er in zo'n situatie gegooid? Waar kan ik dat terugvinden?
In je script door het uit te voeren...
Oké, dan krijg ik een "PHP Fatal error". Hoe vang je die dan op?
"The following error types cannot be handled with a user defined function: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, and most of E_STRICT raised in the file where set_error_handler() is called."
Bron: http://www.php.net/manual/en/function.set-error-handler.php
Bron: http://www.php.net/manual/en/errorfunc.constants.php
Gelukkig kunnen mensen altijd zo goed documentatie lezen...
Bron: http://www.php.net/manual/en/function.set-error-handler.php
| Value | Constant | Description |
| 1 | E_ERROR | Fatal run-time errors. These indicate errors that can not be recovered from, such as a memory allocation problem. Execution of the script is halted. |
| 4 | E_PARSE | Compile-time parse errors. Parse errors should only be generated by the parser. |
| 16 | E_CORE_ERROR | Fatal errors that occur during PHP's initial startup. This is like an E_ERROR, except it is generated by the core of PHP. |
| 32 | E_CORE_WARNING | Warnings (non-fatal errors) that occur during PHP's initial startup. This is like an E_WARNING, except it is generated by the core of PHP. |
| 64 | E_COMPILE_ERROR | Fatal compile-time errors. This is like an E_ERROR, except it is generated by the Zend Scripting Engine. |
| 128 | E_COMPILE_WARNING | Compile-time warnings (non-fatal errors). This is like an E_WARNING, except it is generated by the Zend Scripting Engine. |
| 2048 | E_STRICT | Enable to have PHP suggest changes to your code which will ensure the best interoperability and forward compatibility of your code. |
Bron: http://www.php.net/manual/en/errorfunc.constants.php
Gelukkig kunnen mensen altijd zo goed documentatie lezen...
Gewijzigd op 17/02/2014 20:43:35 door Wouter J
Rustig Wouter, relax... niet iedereen is zo technisch als jij. Niet gelijk zo cynisch worden. Is echt niet nodig.
Ik snap het eerlijk gezegd nog steeds niet. Ik dacht dat je een FATAL error niet kon opvangen? Maar kan dan dus wel???
Ik snap het eerlijk gezegd nog steeds niet. Ik dacht dat je een FATAL error niet kon opvangen? Maar kan dan dus wel???
"The following error types cannot be handled with a user defined function: E_ERROR"
"E_ERROR - Fatal run-time errors"
Hier is niks technisch aan... Gewoon domweg wat engels lezen en iets verder kijken en iets preciezer de doc lezen en iedereen kan hier makkelijk op komen.
"E_ERROR - Fatal run-time errors"
Hier is niks technisch aan... Gewoon domweg wat engels lezen en iets verder kijken en iets preciezer de doc lezen en iedereen kan hier makkelijk op komen.
Nee Wouter, verschillende mensen... verschillende interpretaties. Ik bedoel dit overigens niet lullig tegenover jou, maar jij bent veel technischer dan velen hier op het forum. Dat betekent dat je bepaalde dingen sneller doorziet en dat je sneller verbanden kunt leggen. Wees daar vooral blij om, en probeer andere mensen daarmee te helpen. Maar ga er niet vanuit dat andere mensen hetzelfde denken en kunnen als jij. Ieder mens heeft zijn/haar eigen kwaliteiten op diverse vlakken.
Dat gezegd hebbende... een PHP Fatal error is dus een run-time error? En die kan ik niet opvangen... dus anders gezegd, als er een object wordt aangemaakt dat niet vantevoren is geladen, klapt je applicatie er gewoon uit en daar is niks tegen te doen. Correct?
Dat gezegd hebbende... een PHP Fatal error is dus een run-time error? En die kan ik niet opvangen... dus anders gezegd, als er een object wordt aangemaakt dat niet vantevoren is geladen, klapt je applicatie er gewoon uit en daar is niks tegen te doen. Correct?
Leuk hé PHP?
Even buiten code fouten, de ene keer een catchable error en dan andere keer niet (bv als je bij je database connectie een niet bestaande host opgeeft, kan je dat afvangen met try ... catch)
Even buiten code fouten, de ene keer een catchable error en dan andere keer niet (bv als je bij je database connectie een niet bestaande host opgeeft, kan je dat afvangen met try ... catch)
>> Leuk hé PHP?
Nou :-/
>> de ene keer een catchable error en dan andere keer niet
Ja, in dit geval dus niet... dus vraag ik me af hoe je daar mee om moet gaan. Wat als jij een class aanroept, en om een of andere reden is het class bestand verdwenen. Hoe ga je daar dan mee om? De autoloader een exception laten gooien als het bestand niet bestaat? Ik zie niet echt een andere mogelijkheid :-s
Nou :-/
>> de ene keer een catchable error en dan andere keer niet
Ja, in dit geval dus niet... dus vraag ik me af hoe je daar mee om moet gaan. Wat als jij een class aanroept, en om een of andere reden is het class bestand verdwenen. Hoe ga je daar dan mee om? De autoloader een exception laten gooien als het bestand niet bestaat? Ik zie niet echt een andere mogelijkheid :-s
Niet zo :s(ip), dat hoort bij programeren
Jawel, dat snap ik ook wel. Maar het is niet altijd leuk. Ik probeer een oplossing te vinden, maar niemand kan me helpen, terwijl het toch een probleem zou moeten zijn waar iedereen mee te maken heeft :(
Hmmm, dankjewel voor het meedenken Marcel, maar als ik het goed begrijp kun je de error daarmee niet herstellen. Dus stel dat ik een module wil laden en daar ontbreekt een file, dan kan ik de rest van de pagina niet laden.
Volgens mij is de enige optie om in de autoloader te controleren of het bestand bestaat, en zo niet, dan een exception gooien. Maar waarom reageert er niemand op dit idee? Weten jullie het antwoord ook niet?
Volgens mij is de enige optie om in de autoloader te controleren of het bestand bestaat, en zo niet, dan een exception gooien. Maar waarom reageert er niemand op dit idee? Weten jullie het antwoord ook niet?
In jouw autoloader een exception gooien, en die 3rd party autoloader dan? Heeft die niks meer te zeggen? Het is geen verhaal met 2 kanten: file exists -> class bestaat, file not exists -> class bestaat niet.
En ga eerst eens na of je hele idee wel klopt. Je wilt je applicatie verlaten gaan als er een klasse niet bestaat? Hoe dan? Stel je Container klasse bestaat niet meer, hoe wil de applicatie verder gaan? Hetzelfde geldt voor zowat elke andere klasse die je opvraagt, je vraagt ze namelijk op omdat je ze nodig hebt...
En ga eerst eens na of je hele idee wel klopt. Je wilt je applicatie verlaten gaan als er een klasse niet bestaat? Hoe dan? Stel je Container klasse bestaat niet meer, hoe wil de applicatie verder gaan? Hetzelfde geldt voor zowat elke andere klasse die je opvraagt, je vraagt ze namelijk op omdat je ze nodig hebt...
Volgens mij heb je antwoord zelf al gegeven.
Kortom: Je moet een fatal error voorkomen.
Kortom: Je moet een fatal error voorkomen.
>> In jouw autoloader een exception gooien, en die 3rd party autoloader dan? Heeft die niks meer te zeggen?
Je kent toch namespaces toe aan je autoloader? Op het moment dat een class-naam tot die betreffende namespace behoort, maar het bestand kan niet worden gevonden. Waarom kun je dan geen exception gooien?
>> Stel je Container klasse bestaat niet meer, hoe wil de applicatie verder gaan?
Klopt, ik kan me voorstellen dat je stopt als je container class niet bestaat. Maar probeer het even anders te zien. Stel ik heb op een homepage ergens een blokje "laatste nieuws" staan. Nu kan een bepaalde class van die module niet geladen worden. Moet ik dan de hele website platgooien? Want dat is wat jij nu toch zegt?
Je kent toch namespaces toe aan je autoloader? Op het moment dat een class-naam tot die betreffende namespace behoort, maar het bestand kan niet worden gevonden. Waarom kun je dan geen exception gooien?
>> Stel je Container klasse bestaat niet meer, hoe wil de applicatie verder gaan?
Klopt, ik kan me voorstellen dat je stopt als je container class niet bestaat. Maar probeer het even anders te zien. Stel ik heb op een homepage ergens een blokje "laatste nieuws" staan. Nu kan een bepaalde class van die module niet geladen worden. Moet ik dan de hele website platgooien? Want dat is wat jij nu toch zegt?
Als ik het goed begrijp heb je een autoload class zodat je in je code simpelweg iets als dit kan doen:
Je autoloader laadt die class dan voor je. Nu wil je weten hoe je de error kunt afvangen die je krijgt wanneer je autoloader de opgevraagde class niet kan vinden?
Je hebt daar een aantal opties voor. Je voorkeur hangt een beetje af van wat je precies wilt bereiken. Ik zou in elk geval niet aan "set_error_handler" sleutelen.
Dan is de enige manier om te checken of een class bestaat in je autoloader. Je zou bijvoorbeeld dit kunnen doen:
Je zou bijvoorbeeld ook een soort "Error" object kunnen vullen ipv met exceptions te werken.
Je kan dan bijvoorbeeld altijd nog de "Errors" class uitlezen in je views en daar de melding geven dat een module niet geladen kon worden. Of het wegschrijven naar een log file oid.
Denk alleen dat er wel meer problemen optreden wanneer een module niet gevonden wordt. Waarschijnlijk wordt kort daarna ook die class gebruikt om methods aan te roepen en properties uit te lezen. Maar ja, als er geen instance is gevonden krijgt je natuurlijk weer errors van: "Accessing property on non object" oid.
Dus bedenkt goed of je je applicatie wel echt door wilt laten gaan als een class niet gevonden kan worden. Vaak is dit niet zo'n handig idee.
Je autoloader laadt die class dan voor je. Nu wil je weten hoe je de error kunt afvangen die je krijgt wanneer je autoloader de opgevraagde class niet kan vinden?
Je hebt daar een aantal opties voor. Je voorkeur hangt een beetje af van wat je precies wilt bereiken. Ik zou in elk geval niet aan "set_error_handler" sleutelen.
Dan is de enige manier om te checken of een class bestaat in je autoloader. Je zou bijvoorbeeld dit kunnen doen:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
function __autoload($name) {
if(class_exists($name)) {
require_once($name);
}
else {
throw new MissingException("Kan class $name niet vinden.");
}
}
try {
$obj = new EenClassDieNietBestaat();
} catch (Exception $e) {
echo $e->getMessage(), "\n";
}
if(class_exists($name)) {
require_once($name);
}
else {
throw new MissingException("Kan class $name niet vinden.");
}
}
try {
$obj = new EenClassDieNietBestaat();
} catch (Exception $e) {
echo $e->getMessage(), "\n";
}
Je zou bijvoorbeeld ook een soort "Error" object kunnen vullen ipv met exceptions te werken.
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
function __autoload($name) {
if(class_exists($name)) {
require_once($name);
}
else {
Errors::Add ( "Kan class $name niet vinden." );
}
}
if(class_exists($name)) {
require_once($name);
}
else {
Errors::Add ( "Kan class $name niet vinden." );
}
}
Je kan dan bijvoorbeeld altijd nog de "Errors" class uitlezen in je views en daar de melding geven dat een module niet geladen kon worden. Of het wegschrijven naar een log file oid.
Denk alleen dat er wel meer problemen optreden wanneer een module niet gevonden wordt. Waarschijnlijk wordt kort daarna ook die class gebruikt om methods aan te roepen en properties uit te lezen. Maar ja, als er geen instance is gevonden krijgt je natuurlijk weer errors van: "Accessing property on non object" oid.
Dus bedenkt goed of je je applicatie wel echt door wilt laten gaan als een class niet gevonden kan worden. Vaak is dit niet zo'n handig idee.
Gewijzigd op 19/02/2014 13:13:26 door D Vivendi
Vivendi, het is beter om spl_autoload_register te gebruiken, aangezien die meerdere autoloaders chained.
Ja klopt, dat weet ik. Ik gebruikte __autoload meer als simpele illustratie. Maar inderdaad, de spl_autoload class hiervoor had misschien beter geweest om als voorbeeld te geven.
Gewijzigd op 19/02/2014 13:21:54 door D Vivendi




