Re: [PHP-DEV] autoloading and undefined class constants

2009-07-06 Thread Nathan Nobbe
On Sun, Jul 5, 2009 at 10:21 PM, Ben Bidner b...@vuetec.com wrote:

  per the manual, exceptions thrown in an autoload method are swallowed,
  and an E_ERROR is triggered by php.
 
  http://us2.php.net/manual/en/language.oop5.autoload.php

 I have read that note before, and wondered exactly what it was referring to
 since you can throw exceptions within an autoloader and catch them (or have
 your exception handler do whatever it needs to do with them).

 ?php

   function autoloader($className)
   {
  echo autoloading . PHP_EOL;
   throw new Exception(Fail);
   }

   spl_autoload_register(autoloader);

try
   {
  // Exception
  $obj = new NonExistentClass;
   }
   catch(Exception $e)
   {
  echo caught . PHP_EOL;
   }

   try
   {
  // Exception
  $const = constant(NonExistentClass::NON_EXISTENT_CONSTANT);
   }
   catch(Exception $e)
   {
  echo caught . PHP_EOL;
   }

   try
   {
  // Fatal error
  $const = NonExistentClass::NON_EXISTENT_CONSTANT;
   }
   catch(Exception $e)
   {
  echo never happens . PHP_EOL;
   }
 ?

 Will output:

 autoloading
 caught
 autoloading
 caught
 autoloading
 PHP Fatal error: Undefined class constant


on both my systems (mentioned in reply to rob) the script fatals after the
first autoloading, just like the manual says..

nat...@trident2:~$ php testcode.php
autoloading

Fatal error: Class 'NonExistentClass' not found in /home/nathan/testcode.php
on line 41

-nathan


Re: [PHP-DEV] autoloading and undefined class constants

2009-07-06 Thread Alexey Zakhlestin
On Mon, Jul 6, 2009 at 6:49 AM, Ben Bidnerb...@vuetec.com wrote:

 ?php

   function autoloader($className)
   {
      throw new Exception(Fail);
   }

   spl_autoload_register(autoloader);

The whole point of spl_autoload_register() is to allow programmers to
have several independent autoloaders. So, it is a bad practice to
throw exception from autoload — doing so, you forbid system to try the
next autoloader.

Good practice is: if you can't load class from autoloader — just
silently return from it

-- 
Alexey Zakhlestin
http://www.milkfarmsoft.com/

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-DEV] autoloading and undefined class constants

2009-07-05 Thread Ben Bidner
Hi folks,

Just looking for a quick clarification on how class constant look ups are
performed internally under circumstances when an autoload function is also
called.


Consider the following example:

?php

   function autoloader($className)
   {
  throw new Exception(Fail);
   }

   spl_autoload_register(autoloader);

?

?php

   // Exception
   $obj = new NonExistantClass;

?

?php

   // Fatal error
   $const = NonExistantClass::NON_EXISTANT_CONSTANT;

?

I would have assumed that since the autoloader threw an exception while
attempting to load the non existant class, that internally, there would be
no attempt to access the non existant constant (since surely that comes
after the exception was thrown???) and we would get the Exception, rather
than a Fatal error.

Intended or a design error?


Ben Bidner

+61.7.3161.2000 (office) | +61.7.3009.0651 (fax) | +61.4.3201.5362 (mobile)
http://www.vuetec.com/



-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] autoloading and undefined class constants

2009-07-05 Thread Nathan Nobbe
On Sun, Jul 5, 2009 at 8:49 PM, Ben Bidner b...@vuetec.com wrote:

 Hi folks,

 Just looking for a quick clarification on how class constant look ups are
 performed internally under circumstances when an autoload function is also
 called.


 Consider the following example:

 ?php

   function autoloader($className)
   {
  throw new Exception(Fail);
   }

   spl_autoload_register(autoloader);

 ?

 ?php

   // Exception
   $obj = new NonExistantClass;

 ?

 ?php

   // Fatal error
   $const = NonExistantClass::NON_EXISTANT_CONSTANT;

 ?

 I would have assumed that since the autoloader threw an exception while
 attempting to load the non existant class, that internally, there would be
 no attempt to access the non existant constant (since surely that comes
 after the exception was thrown???) and we would get the Exception, rather
 than a Fatal error.

 Intended or a design error?


per the manual, exceptions thrown in an autoload method are swallowed, and
an E_ERROR is triggered by php.

http://us2.php.net/manual/en/language.oop5.autoload.php

personally, i dont know why it works this way.. even if you register an
error handler, you cant handle it from user-space, b/c set_error_handler()
only lets you handle E_USER_ERROR..  there are 2 issues this presents,
1. if your autoloading logic creates a message that it would pass through to
higher level code, via exceptions or errors, they are swallowed, so you dont
know what went wrong.
2. if you call die() you can log the message, however youll not be able to
leverage standard error handling code here, at least not via a thrown
exception or triggered error

the only solution ive found is to invoke the standard error handling code
directly from the autoloading logic.

imo, this defeats the purpose of the loose coupling errors and exceptions
provide.  one of the reasons its really painful is because the autoloader is
startup code.., which means you cant leverage it to load its dependecies,
which means your error logging code cant leverage the autoloading logic iff
the autoloading logic has to call the error handling logic directly:(  when
i say 'standard error handling logic' i mean like loading up a static html
page, or similar.

i think, since failures in autoload result in an E_ERROR, it would at least
make sense to allow user-space to trigger E_USER_ERROR, which PHP could
allow to pass through the autoload method untouched.  i think this is
reasonable, b/c E_USER_ERROR still interrupts program execution, and then
userspace could leverage the same error handling code it does for everything
else when problems occur with autoloading.

id seen some posts on php.net about using output buffering to be able to
trap E_ERROR but then came to discover that output buffering has been
disabled on the cli since like 4.3.5, so the example code like,

?php
ob_start();
call_fake_function();
?

would blow up w/ a fatal on all my installations.  id post on php-general
about it, but im more curious to see what internals folks think about it.

-nathan


RE: [PHP-DEV] autoloading and undefined class constants

2009-07-05 Thread Ben Bidner
 per the manual, exceptions thrown in an autoload method are swallowed,
 and an E_ERROR is triggered by php.

 http://us2.php.net/manual/en/language.oop5.autoload.php

I have read that note before, and wondered exactly what it was referring to 
since you can throw exceptions within an autoloader and catch them (or have 
your exception handler do whatever it needs to do with them).

?php

   function autoloader($className)
   {
  echo autoloading . PHP_EOL;
  throw new Exception(Fail);
   }

   spl_autoload_register(autoloader);

   try
   {
  // Exception
  $obj = new NonExistentClass;
   }
   catch(Exception $e)
   {
  echo caught . PHP_EOL;
   }

   try
   {
  // Exception
  $const = constant(NonExistentClass::NON_EXISTENT_CONSTANT);
   }
   catch(Exception $e)
   {
  echo caught . PHP_EOL;
   }

   try
   {
  // Fatal error
  $const = NonExistentClass::NON_EXISTENT_CONSTANT;
   }
   catch(Exception $e)
   {
  echo never happens . PHP_EOL;
   }
?

Will output:

autoloading
caught
autoloading
caught
autoloading
PHP Fatal error: Undefined class constant


I would expect accessing a constant directly to behave as constant() does at 
the moment  and I would expect constant() to behave as the manual says it 
does (and return NULL for non existent class constants instead of throwing 
E_ERRORs).


Ben Bidner

+61.7.3161.2000 (office) | +61.7.3009.0651 (fax) | +61.4.3201.5362 (mobile)
http://www.vuetec.com/


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php