# Why do disabled functions / classes generate a WARNING.

- Thread: https://externals.io/message/61992
- Original archive: https://news-web.php.net/php.internals/61992
- Started by Leigh on 2012-08-03T07:08:40+00:00
- Messages: 14
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #61992 — Leigh — 2012-08-03T07:08:40+00:00

URL: https://externals.io/message/61992#61992

Hi all,

Can anyone explain to me the reason that when a function or class is
disabled via the ini setting, an attempt to access the disabled item
generates a non-fatal error?

I'm looking at a segfault in the SPL caused by the blind creation of a
class, which seems to only fail when the class is disabled. I'm
wondering in how many other places this could occur.

The obvious solution is to be more careful and check return values,
but a FATAL would also have prevented execution continuing.

Thanks,

Leigh.

---

## #62001 — Hannes Magnusson — 2012-08-03T11:33:40+00:00

URL: https://externals.io/message/61992#62001 · In reply to: #61992

> Hi all,
>
> Can anyone explain to me the reason that when a function or class is
> disabled via the ini setting, an attempt to access the disabled item
> generates a non-fatal error?

Because there isn't anything actually wrong.

A fatal error is reserved for things we cannot recover from, but a
disabled function is easily recoverable.

-Hannes

---

## #62002 — Leigh — 2012-08-03T11:59:37+00:00

URL: https://externals.io/message/61992#62002 · In reply to: #62001

> Because there isn't anything actually wrong.
>
> A fatal error is reserved for things we cannot recover from, but a
> disabled function is easily recoverable.

I don't see how it is any more recoverable than the function/class not
existing at all. How much code do you know of that checks for the
existence of every function it expects to be there, before using it?
The matter is even worse with classes, since creating a disabled class
does not return null. It returns an instantiated object with no
methods.

When an unexpected function is disabled, the engine can recover, sure.
The code, probably not. In my opinion it's better to stop the code
doing something potentially harmful than allowing it to continue with
bad data.

It seems inconsistent to me.

--

$a = new UndefinedClass; // PHP Fatal error:  Class 'UndefinedClass' not found

--

$a = new DisabledClass; // Warning
var_dump(get_class($a)); // string(13) "disabledclass"

--

$a = undefinedFunction(); // PHP Fatal error:  Call to undefined
function undefinedFunction()

--

$a = disabledFunction(); // Warning
var_dump($a); // null

---

## #62003 — Etienne Kneuss — 2012-08-03T12:05:35+00:00

URL: https://externals.io/message/61992#62003 · In reply to: #62002

> > […]

Another great use-case for engine-thrown exceptions.

IMHO we should really rethink the "let's not throw exceptions from the
engine/normal code so that people don't have to learn them"


-- 
Etienne Kneuss

---

## #62005 — Stan Vass — 2012-08-03T14:19:05+00:00

URL: https://externals.io/message/61992#62005 · In reply to: #61992

> Hi all,
>
> Can anyone explain to me the reason that when a function or class is
> disabled via the ini setting, an attempt to access the disabled item
> generates a non-fatal error?
>
> I'm looking at a segfault in the SPL caused by the blind creation of a
> class, which seems to only fail when the class is disabled. I'm
> wondering in how many other places this could occur.
>
> The obvious solution is to be more careful and check return values,
> but a FATAL would also have prevented execution continuing.
>
> Thanks,
>
> Leigh.

PHP has a long history of issuing errors of the wrong type at the wrong 
time. My experience shows it's best to have an error handler convert all 
errors to catchable exceptions, with some error types (like E_STRICT, 
 `E_ERROR` etc.) to become instant fatal errors (can't be caught).

This would also solve your use case since the warning will become an 
exception with a stack trace clearly pointing to the origin of your problem. 
Additionally you can handle an exception on a higher level in the stack once 
instead of doing it for every function/class call.

I'm afraid fixing the default behavior is a big hopeless since it'll break 
BC and require a major rethinking of the way PHP issues errors.

See: `set_error_handler()`.

Stan

---

## #62006 — Laruence — 2012-08-03T14:27:48+00:00

URL: https://externals.io/message/61992#62006 · In reply to: #61992

> Hi all,
>
> Can anyone explain to me the reason that when a function or class is
> disabled via the ini setting, an attempt to access the disabled item
> generates a non-fatal error?
>
> I'm looking at a segfault in the SPL caused by the blind creation of a
> class, which seems to only fail when the class is disabled. I'm
> wondering in how many other places this could occur.
>
> The obvious solution is to be more careful and check return values,
> but a FATAL would also have prevented execution continuing.
>
> Thanks,
>
> Leigh.
Hi:

this is a very badly bug.

but I think it's not a spl issues, we should change the behavior of
zend_disable_class,

since for now, it will delete the class entry, which will make the class entry
pointer (preserved by extension) become a wild pointer..

dereference it is a undefined behavior, in this sense, segfault is lucky.

thanks
>
> --
> 
> 
>



-- 
Laruence  Xinchen Hui
http://www.laruence.com/

---

## #62009 — Ferenc Kovacs — 2012-08-03T15:50:20+00:00

URL: https://externals.io/message/61992#62009 · In reply to: #62005

> Hi all,
> > […]
>
> PHP has a long history of issuing errors of the wrong type at the wrong
> time. My experience shows it's best to have an error handler convert all
> errors to catchable exceptions, with some error types (like E_STRICT,
> `E_ERROR` etc.) to become instant fatal errors (can't be caught).
>
> This would also solve your use case since the warning will become an
> exception with a stack trace clearly pointing to the origin of your
> problem. Additionally you can handle an exception on a higher level in the
> stack once instead of doing it for every function/class call.
>
> I'm afraid fixing the default behavior is a big hopeless since it'll break
> BC and require a major rethinking of the way PHP issues errors.
>
> See: `set_error_handler()`.
>
>
a php function/operation can raise more than one warning, how would you
handle that?
with exceptions you would only get the first one.
another issue is that with the current error handling model a call can
trigger a non-fatal error and still return some data.
with exeptions you can't do that.
so changing our internal error handling isn't as easy to start throwing
ErrorException-s, it would require much more workthan that.

-- 
Ferenc Kovács
@Tyr43l - http://tyrael.hu

---

## #62010 — Andrew Faulds — 2012-08-03T15:52:23+00:00

URL: https://externals.io/message/61992#62010 · In reply to: #62009

> 
>
> > […]
> a php function/operation can raise more than one warning, how would you
> handle that?
> with exceptions you would only get the first one.
> another issue is that with the current error handling model a call can
> trigger a non-fatal error and still return some data.
> with exeptions you can't do that.
> so changing our internal error handling isn't as easy to start throwing
> ErrorException-s, it would require much more workthan that.
>
Warnings are special, they aren't really errors as such. They wouldn't 
become exceptions.

Also, why should an erroring function return a value?

-- 
Andrew Faulds
http://ajf.me/

---

## #62012 — Ferenc Kovacs — 2012-08-03T16:04:18+00:00

URL: https://externals.io/message/61992#62012 · In reply to: #62010

>
>
> > […]
> become exceptions.
>
> Also, why should an erroring function return a value?
>
>
from
"My experience shows it's best to have an error handler convert all errors
to catchable exceptions, with some error types (like E_STRICT, `E_ERROR` 
etc.) to become instant fatal errors (can't be caught)."
I think he is talking about turning everything(E_NOTICE, E_WARNING, etc.)
into exceptions except a few, which can't be catched (why should `E_STRICT` 
be uncatchable?! ).
Which brings up the issues that I mentioned before.
Getting the return of an erroring function isn't such a big issue, but
turning everything into exceptions would prevent getting any return value
from any function/operation which triggers anything,

Personally I think that turning everything into exceptions is a bad idea,
and it would make stuff which possible currently impossible.
On the other hand, I think that we have many `E_ERROR` which could be turned
into E_RECOVERABLE_ERROR.
Which in turn could be turned into Exception by an userland error handler
if the php userland developer wishes it.

-- 
Ferenc Kovács
@Tyr43l - http://tyrael.hu

---

## #62014 — Andrew Faulds — 2012-08-03T16:10:43+00:00

URL: https://externals.io/message/61992#62014 · In reply to: #62012

>
>
>     Warnings are special, they aren't really errors as such. They
>     wouldn't become exceptions.
>
>     Also, why should an erroring function return a value?
>
>
> from
> "My experience shows it's best to have an error handler convert all 
> errors to catchable exceptions, with some error types (like E_STRICT, 
> `E_ERROR` etc.) to become instant fatal errors (can't be caught)."
> I think he is talking about turning everything(E_NOTICE, E_WARNING, 
> etc.) into exceptions except a few, which can't be catched (why should 
> `E_STRICT` be uncatchable?! ).
Of course some can't be caught. The kind that can't are ones that can't 
be for obvious reasons. Runtime errors, for instance.
> Which brings up the issues that I mentioned before.
> Getting the return of an erroring function isn't such a big issue, but 
> turning everything into exceptions would prevent getting any return 
> value from any function/operation which triggers anything,
I don't see how the return value is needed if it has errored. Warnings 
are different, but they wouldn't become exceptions.
>
> Personally I think that turning everything into exceptions is a bad 
> idea, and it would make stuff which possible currently impossible.
Examples, please? I think making more things into exceptions, and hence 
catchable, makes more stuff possible (recovering from trying to use 
non-existent functions, for example)
> On the other hand, I think that we have many `E_ERROR` which could be 
> turned into E_RECOVERABLE_ERROR.
> Which in turn could be turned into Exception by an userland error 
> handler if the php userland developer wishes it.
Why not just have them exceptions in the first place?
>
> -- 
> Ferenc Kovács
> @Tyr43l - http://tyrael.hu


-- 
Andrew Faulds
http://ajf.me/

---

## #62015 — Stan Vass — 2012-08-03T16:36:21+00:00

URL: https://externals.io/message/61992#62015 · In reply to: #62009

a php function/operation can raise more than one warning, how would you handle that?
  with exceptions you would only get the first one.
  another issue is that with the current error handling model a call can trigger a non-fatal error and still return some data.
  with exeptions you can't do that.
  so changing our internal error handling isn't as easy to start throwing ErrorException-s, it would require much more workthan that.


Yes it is a bit more work than that. For example include issues two errors on include failure, I mute one of them and turn the other into an exception, which is one of the behaviors you've mentioned. There are ways to fix everything, but you have to be specific, if you want me to be specific as well.

Either way I'm trying to give a practical solution you can implement today. Aside from practicality, I do also support the idea that accessing disabled symbols should be a fatal error, not a warning.

Stan

---

## #62016 — Stan Vass — 2012-08-03T16:42:00+00:00

URL: https://externals.io/message/61992#62016 · In reply to: #62012

Which brings up the issues that I mentioned before.

  Getting the return of an erroring function isn't such a big issue, but turning everything into exceptions would prevent getting any return value from any function/operation which triggers anything,

Maybe you want to keep your cake and eat it too, but in practice, functions which return useful content and also error are simply poorly designed.
You can work around such function, for example if I absolutely need both channels, exception AND return value, I have this:

1) switch the error handler in a temporary mode which logs errors in an array without throwing them.
2) call the offending function
3) preserve the return value and read the log
4) create an exception class instance which contains all needed data
5) throw it.

Alternatively I can choose to just return the value and not throw anything, depends what makes most sense. I wrap this once and then I can call it just as usual, getting both channels. BUT, this is very rare, and is a sign of a poor design of the function IMHO.

Stan

---

## #62017 — Stas Malyshev — 2012-08-03T16:47:36+00:00

URL: https://externals.io/message/61992#62017 · In reply to: #61992

Hi!

> I'm looking at a segfault in the SPL caused by the blind creation of a
> class, which seems to only fail when the class is disabled. I'm
> wondering in how many other places this could occur.

This seems to be pretty bad. I'd say creation of an instance of disabled
class should be a fatal error, but regardless SPL should handle returns
properly. Did you submit a bug about the SPL problem?

-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #62018 — Laruence — 2012-08-03T17:01:34+00:00

URL: https://externals.io/message/61992#62018 · In reply to: #62017

> Hi!
>
> > […]
>
> This seems to be pretty bad. I'd say creation of an instance of disabled
> class should be a fatal error, but regardless SPL should handle returns
> properly. Did you submit a bug about the SPL problem?

I think it's https://bugs.php.net/bug.php?id=62737

thanks
>
> --
> Stanislav Malyshev, Software Architect
> SugarCRM: http://www.sugarcrm.com/
> (408)454-6900 ext. 227
>
> --
> 
> 
>



-- 
Laruence  Xinchen Hui
http://www.laruence.com/
