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

[PHP] Spl Autoloader icm. class_exists

Pagina: 1
Acties:

  • Robbiedobbie
  • Registratie: Augustus 2009
  • Laatst online: 16:27
Ik ben momenteel in php aan het kloten met een stom probleempje, welk normaal gesproken toch simpel opgelost zou moeten kunnen worden.

Ik heb recent een projectje gemaakt wat gebruikt maakt van class autoloading. Hierbij gebruik ik de standaard spl_autoload_register() functie. Dit werkt normaal gesproken gewoon goed, en is sneller dan wanneer ik een eigen functie implementeer (omdat de standaard gemaakt is in C en is meegenomen in PHP).

Ik heb een errorhandler geregistreerd die alle php errors omzet in exceptions. Deze heeft de volgende code (indien relevant):
PHP:
1
2
3
function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}


Nu wilde ik bij een functie kijken of een bepaalde class bestond, en wanneer dit zo was, een instantie aanmaken. Hiervoor wilde ik gebruik maken van class_exists(). Dit werkt goed zolang de class bestaat. Wanneer deze echter niet bestaat, wordt er een LogicException gegooid dat de class niet geladen kan worden.

Dit is vervelend, echter dacht ik het op te lossen door de exception af te vangen en daarmee alsnog de code te runnen die gerund moet worden als de class niet bestaat. Dit lukt echter niet. Ik heb hem in een try catch clossure gezet, welke alle exceptions af moet vangen. Echter knalt het script er nog steeds uit met een fatal error omdat die exception niet gecatched zou worden. Wanneer ik ben aan het debuggen, merk ik inderdaad dat de code in het catchblok niet wordt gerunned.

Het gaat om deze code:

PHP:
1
2
3
4
5
6
7
8
try {
    if(class_exists($class)) {
        $pageInstance = new $class;
        //run code using the class
    }
} catch(Exception $e) {
    //run code for when class is not found
}


Zie ik nou iets over het hoofd?

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 20:03

MueR

Admin Devschuur® & Discord

is niet lief

Een error is geen exception. Het idee van autoloading is dat je classes gewoon aanroept en de autoloader deze voor je gaat opzoeken. Het gebruik van class_exists icm een autoloader werkt dan ook niet.

Anyone who gets in between me and my morning coffee should be insecure.


  • Robbiedobbie
  • Registratie: Augustus 2009
  • Laatst online: 16:27
Ik snap dat een error geen exception is. Echter ontstaat deze error omdat een exceptie niet gecatched zou worden. Dit terwijl de exceptie wordt gegooid in een try/catch blok.

Hoe zou ik dit dan kunnen aanpakken zonder class_exists of iets dergelijks te gebruiken?

  • Cartman!
  • Registratie: April 2000
  • Niet online
Wat is het doel van die error afvangen in een exception dan? Als je tijdens developen tegenkomt dat een class niet geladen is dan check je de paden of maak je die class aan zodat ie daarna wel te vinden is.

  • Robbiedobbie
  • Registratie: Augustus 2009
  • Laatst online: 16:27
Het doel was eigenlijk een extreem modulair systeem waar je widgets los kan ontwikkelen en erbij kan knallen, en dan in de config alleen de widgetnaam bij een bepaalde pagina toe te voegen. Echter wilde ik die fout netjes afvangen.

EDIT: Ik heb net gevonden waardoor de exception niet werd gecatched. Iemand op deze pagina had hetzelfde probleem: http://stackoverflow.com/...rouble-catching-exception. Ik werk met namespaces en dan heeft php de leuke functie om de exception ook in die namespace te zoeken 8)7

Een simpele \ voor de exceptionname was de oplossing...

[ Voor 41% gewijzigd door Robbiedobbie op 01-06-2013 17:16 . Reden: Oplossing gevondden ]


  • Barryvdh
  • Registratie: Juni 2003
  • Laatst online: 21:50
Maar met autoloading roep je toch niet die class aan? Volgens mij wordt die functie gewoon aangeroepen als de class niet gevonden wordt en dan kan je een php bestand includen waarin de class te vinden is.
(En er is een standaard voor he, PSR-0, die je zou kunnen gebruiken, inclusief voorbeeld implementatie; http://www.php-fig.org/psr/0/)

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

drm

f0pc0dert

MueR::
Een error is geen exception. Het idee van autoloading is dat je classes gewoon aanroept en de autoloader deze voor je gaat opzoeken. Het gebruik van class_exists icm een autoloader werkt dan ook niet.
Parameters

class_name
The class name. The name is matched in a case-insensitive manner.

autoload
Whether or not to call __autoload by default.

Robbiedobbie:
Echter knalt het script er nog steeds uit met een fatal error omdat die exception niet gecatched zou worden. Wanneer ik ben aan het debuggen, merk ik inderdaad dat de code in het catchblok niet wordt gerunned.

Het gaat om deze code:

PHP:
1
2
3
4
5
6
7
8
try {
    if(class_exists($class)) {
        $pageInstance = new $class;
        //run code using the class
    }
} catch(Exception $e) {
    //run code for when class is not found
}


Zie ik nou iets over het hoofd?
Je opzet klopt volgens mij wel. Ik vraag me alleen af waar die LogicException vandaan zou moeten komen, want class_exists() hoort geen error the throwen als een class niet bestaat; die geeft gewoon true of false terug. Die LogicException komt dan uit je eigen autoloader neem ik aan?

Is het geen namespacing probleem? Als je Exception afvangt binnen een namespace is het een local name en dus wordt de local name gebruikt om hem af te vangen:

PHP:
1
2
3
4
5
6
7
8
9
namespace Foo;

try {
    bar();
} catch (Exception $e) {
    // catching 'Foo\Exception' here.
} catch (\Exception $e) {
    // catching all other exceptions here.
}

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


  • Robbiedobbie
  • Registratie: Augustus 2009
  • Laatst online: 16:27
Die exception wordt gegooid door de standaard spl-autoloader in php. Ik heb geen eigen gemaakt omdat de standaard sneller is in runtime.

Het probleem is inderdaad al opgelost. Het was inderdaad een namespacing probleem (zie ook vorig bericht). Ik denk dat ik nog moet wennen aan namespaces in php doordat de standaard functies niet in een eigen namespace zitten. Ik ben meer gewend aan de namespaces van c++ en vooral de packages van Java.

Bedankt voor de hulp!
Pagina: 1