I can't seem to find any discussion on this BC issue, so forgive me if
this has already been discussed.
Given the following;
$a = 'a string';
/* E_ERROR
Cannot use string offset as an array */
echo is_array($a['bar']['baz']);
/* non error resolution */
echo isset($a['bar']['baz']) && is_array($a['bar']['baz']);
I'm not sure, but the patch below does seem to make the E_ERROR
get demoted to a E_WARNING, thus fixing it so execution simply doesn't
stop when a string is referenced improperly. Or is it a must that php
needs to stop in this case?
Index: zend_execute.c
RCS file: /repository/ZendEngine2/zend_execute.c,v
retrieving revision 1.643
diff -u -r1.643 zend_execute.c
--- zend_execute.c 15 Apr 2004 21:32:34 -0000 1.643
+++ zend_execute.c 27 Apr 2004 02:39:52 -0000
@@ -898,7 +898,9 @@
zval ***retval = &T(result->u.var).var.ptr_ptr;
if (!container_ptr) {
-
zend_error(E_ERROR, "Cannot use string offset as an array");
-
*retval = &EG(uninitialized_zval_ptr);
-
zend_error(E_WARNING, "Cannot use string offset as an array");
-
return; } container = *container_ptr;
Curt
"I used to think I was indecisive, but now I'm not so sure."
I can't seem to find any discussion on this BC issue, so forgive me if
this has already been discussed.Given the following;
$a = 'a string';
/*
E_ERROR
Cannot use string offset as an array */
echo is_array($a['bar']['baz']);/* non error resolution */
echo isset($a['bar']['baz']) && is_array($a['bar']['baz']);I'm not sure, but the patch below does seem to make the
E_ERROR
get demoted to a E_WARNING, thus fixing it so execution simply doesn't
stop when a string is referenced improperly. Or is it a must that php
needs to stop in this case?
I see no reason why PHP shouldn't stop in this case. You're definitely
doing something wrong to create that E_ERROR.
Derick
I made this change back in December.
I guess I could revert back but I think it makes sense to be strict here.
What does the rest think?
Andi
At 03:49 AM 4/27/2004 +0000, Curt Zirzow wrote:
I can't seem to find any discussion on this BC issue, so forgive me if
this has already been discussed.Given the following;
$a = 'a string';
/*
E_ERROR
Cannot use string offset as an array */
echo is_array($a['bar']['baz']);/* non error resolution */
echo isset($a['bar']['baz']) && is_array($a['bar']['baz']);I'm not sure, but the patch below does seem to make the
E_ERROR
get demoted to a E_WARNING, thus fixing it so execution simply doesn't
stop when a string is referenced improperly. Or is it a must that php
needs to stop in this case?Index: zend_execute.c
RCS file: /repository/ZendEngine2/zend_execute.c,v
retrieving revision 1.643
diff -u -r1.643 zend_execute.c
--- zend_execute.c 15 Apr 2004 21:32:34 -0000 1.643
+++ zend_execute.c 27 Apr 2004 02:39:52 -0000
@@ -898,7 +898,9 @@
zval ***retval = &T(result->u.var).var.ptr_ptr;if (!container_ptr) {
zend_error(E_ERROR, "Cannot use string offset as an array");
*retval = &EG(uninitialized_zval_ptr);
zend_error(E_WARNING, "Cannot use string offset as an array");
return; } container = *container_ptr;
Curt
"I used to think I was indecisive, but now I'm not so sure."
Andi Gutmans wrote:
At 03:49 AM 4/27/2004 +0000, Curt Zirzow wrote:
$a = 'a string';
/*E_ERROR
Cannot use string offset as an array */
echo is_array($a['bar']['baz']);I made this change back in December.
I guess I could revert back but I think it makes sense to be strict here.
What does the rest think?
My feeling is that the is_-functions should be forgiving as people
are doing checks to ensure proper input values. To force a combination
or isset and is_ seems to be the wrong thing to me. But I realize that
the issue here happens because is_* are normal functions and the check
is done beforehand. Nevertheless I'd prefer not to have to guard is_*
with isset in my ideal PHP world :-)
On one hand it's not that important to me though as it only happens
under rare circumstances. On the other hand it leads to very subtle BC
problems as you can hit it depending on user input in a form if you use
nested arrays there. So I'm 50:50 on reverting.
- Chris
Hello Andi,
be strict
marcus
Tuesday, April 27, 2004, 9:51:35 AM, you wrote:
I made this change back in December.
I guess I could revert back but I think it makes sense to be strict here.
What does the rest think?
Andi
At 03:49 AM 4/27/2004 +0000, Curt Zirzow wrote:
I can't seem to find any discussion on this BC issue, so forgive me if
this has already been discussed.Given the following;
$a = 'a string';
/*
E_ERROR
Cannot use string offset as an array */
echo is_array($a['bar']['baz']);/* non error resolution */
echo isset($a['bar']['baz']) && is_array($a['bar']['baz']);I'm not sure, but the patch below does seem to make the
E_ERROR
get demoted to a E_WARNING, thus fixing it so execution simply doesn't
stop when a string is referenced improperly. Or is it a must that php
needs to stop in this case?Index: zend_execute.c
RCS file: /repository/ZendEngine2/zend_execute.c,v
retrieving revision 1.643
diff -u -r1.643 zend_execute.c
--- zend_execute.c 15 Apr 2004 21:32:34 -0000 1.643
+++ zend_execute.c 27 Apr 2004 02:39:52 -0000
@@ -898,7 +898,9 @@
zval ***retval = &T(result->u.var).var.ptr_ptr;if (!container_ptr) {
zend_error(E_ERROR, "Cannot use string offset as an array");
*retval = &EG(uninitialized_zval_ptr);
zend_error(E_WARNING, "Cannot use string offset as an array");
return; } container = *container_ptr;
Andi Gutmans wrote:
I made this change back in December.
I guess I could revert back but I think it makes sense to be strict here.
Reevaluating it I noted the following:
$a = 'foo'; $a['bar']['qux'] = 42; # error
$a = 42; $a['bar']['qux'] = 42; # warning
$a = true; $a['bar']['qux'] = 42; # warning
unset($a); $a['bar']['qux'] = 42; # works
$a = null; $a['bar']['qux'] = 42; # works
$a = false; $a['bar']['qux'] = 42; # works!
On the other hand
$a = 'foo'; $b = $a['bar']['qux']; # error
$a = 42; $b = $a['bar']['qux']; # works
$a = true; $b = $a['bar']['qux']; # works
unset($a); $b = $a['bar']['qux']; # works
$a = null; $b = $a['bar']['qux']; # works
$a = false; $b = $a['bar']['qux']; # works
Let me ask you one question: What it the real benefit of making it
fail? Isn't a notice or warning enough safety?
I think this should definitely be more orthogonal, i.e. work (with a
notice or warning) in all cases to avoid WTF.
[ $a = 'foo'; $a['bar'] = 42; has an even weirder behaviour: It results
in the string '4oo'... ]
- Chris
Hello Christian,
thanks for the test
Tuesday, April 27, 2004, 12:20:36 PM, you wrote:
Andi Gutmans wrote:
I made this change back in December.
I guess I could revert back but I think it makes sense to be strict here.
Reevaluating it I noted the following:
$a = 'foo'; $a['bar']['qux'] = 42; # error
$a = 42; $a['bar']['qux'] = 42; # warning
$a = true; $a['bar']['qux'] = 42; # warning
unset($a); $a['bar']['qux'] = 42; # works
$a = null; $a['bar']['qux'] = 42; # works
$a = false; $a['bar']['qux'] = 42; # works!
false should have the same behavior as other scalar values maybe null
is discussable but then again it is a value like 0 of true or 42 just
with a little specific meaning.
On the other hand
$a = 'foo'; $b = $a['bar']['qux']; # error
$a = 42; $b = $a['bar']['qux']; # works
$a = true; $b = $a['bar']['qux']; # works
unset($a); $b = $a['bar']['qux']; # works
$a = null; $b = $a['bar']['qux']; # works
$a = false; $b = $a['bar']['qux']; # works
Having these working without notice/wraning/error if it does without
the assignment is a miserable inconsistency.
Let me ask you one question: What it the real benefit of making it
fail? Isn't a notice or warning enough safety?
I think this should definitely be more orthogonal, i.e. work (with a
notice or warning) in all cases to avoid WTF.
agreed
[ $a = 'foo'; $a['bar'] = 42; has an even weirder behaviour: It results
in the string '4oo'... ]
That's a pretty. It is using 'bar' as a sting index to 'foo' and to do
this it needs to convert 'bar' to an integer. The rest is obvious.
I think we should make [] as string offset an E_STRICT
or even E_ERROR
because it confuses far too many people especially since we generally
have autoconversions and it is not clear what the result of such
expressions is without trying them.
--
Best regards,
Marcus mailto:helly@php.net
Marcus Boerger wrote:
[ $a = 'foo'; $a['bar'] = 42; has an even weirder behaviour: It results
in the string '4oo'... ]That's a pretty. It is using 'bar' as a sting index to 'foo' and to do
this it needs to convert 'bar' to an integer. The rest is obvious.
So you find it obvious that 42 is cast to string and the first character
is used as replacement? Wasn't obvious to me before I tried it :-)
I think we should make [] as string offset an
E_STRICT
or evenE_ERROR
because it confuses far too many people especially since we generally
E_ERROR
would be a big BC break I guess. E_STRICT
sounds fine to me.
- Chris
Hello Christian,
Tuesday, April 27, 2004, 1:34:47 PM, you wrote:
Marcus Boerger wrote:
[ $a = 'foo'; $a['bar'] = 42; has an even weirder behaviour: It results
in the string '4oo'... ]That's a pretty. It is using 'bar' as a sting index to 'foo' and to do
this it needs to convert 'bar' to an integer. The rest is obvious.
So you find it obvious that 42 is cast to string and the first character
is used as replacement? Wasn't obvious to me before I tried it :-)
That's what i meant it confuses far too many people and doesn't even make
real sense. For example converting 42 into chr(42) and setting it would
follow the same autoconversion logic. Hence a hint of kind E_STRICT
would
be very good.
marcus
Hello Christian,
Tuesday, April 27, 2004, 1:34:47 PM, you wrote:
Marcus Boerger wrote:
[ $a = 'foo'; $a['bar'] = 42; has an even weirder behaviour: It results
in the string '4oo'... ]That's a pretty. It is using 'bar' as a sting index to 'foo' and to do
this it needs to convert 'bar' to an integer. The rest is obvious.So you find it obvious that 42 is cast to string and the first character
is used as replacement? Wasn't obvious to me before I tried it :-)That's what i meant it confuses far too many people and doesn't even make
real sense. For example converting 42 into chr(42) and setting it would
follow the same autoconversion logic. Hence a hint of kindE_STRICT
would
be very good.
I know I have no karma here, but anyway:
If you want to give people a hinting they access their stuff in a
wrong way and you want it in a consistent way:
why not throw an E_STRICT
(or maybe even an E_NOTICE) when accessing anything
via [] that is not array?
$a = null; $a['foo']; -> should give an E_STRICT
(if not an E_NOTICE)
$a = false; $a['foo']; -> should give an E_STRICT
(if not an E_NOTICE)
$a = "FOO"; $a['foo']; -> should give an E_STRICT
(if not an E_NOTICE)
$a = array(); $a['foo']; -> gives an E_NOTICE
because of "undefined index 'foo'"
$a = array('foo'=>'FOO'); $a['foo'] -> obviously okay
just my few p.
messju
marcus