By: John Nilsson
Date: 2006-07-20
Time: 12:47
|
ArrayAccess and ArrayObject "arrays" and tbs
How do you write tbs templates that reads "offstes" from objects that implements ArrayAccess?
I just get TinyButStrong Error in field [x.y...] : item y' is neither a method nor a property in the class 'X'. This message can be cancelled using parameter 'noerr'.
|
By: Skrol29
Date: 2006-07-20
Time: 14:08
|
Re: ArrayAccess and ArrayObject "arrays" and tbs
Hi,
This should work (not tested):
|
By: Skrol29
Date: 2006-07-20
Time: 14:18
|
Re: ArrayAccess and ArrayObject "arrays" and tbs
Sorry, it should be
(tested)
|
By: John Nilsson
Date: 2006-07-20
Time: 14:32
|
Re: ArrayAccess and ArrayObject "arrays" and tbs
Nah, x.offsetGet(y) worked
... but it's not a perfect sollution I'm affraid.
I tried hacking the tbs source instead.
Trying this patch:
--- tbs.php 2006-07-20 14:29:06.000000000 +0200
+++ tbs_class_php5.php 2006-06-25 18:33:22.000000000 +0200
@@ -890,7 +890,7 @@
if (($SubStart!==false) and $Loc->SubOk) {
for ($i=$SubStart;$i<$Loc->SubNbr;$i++) {
$x = $Loc->SubLst[$i]; // &$Loc... brings an error with Event Example, I don't know why.
- if (is_array($Value) || $Value instanceof ArrayAccess) {
+ if (is_array($Value)) {
if (isset($Value[$x])) {
$Value =& $Value[$x];
} elseif (array_key_exists($x,$Value)) {// can happens when value is NULL
didn't work to well.
"Fatal error: Objects used as arrays in post/pre increment/decrement must return values by reference in tbs.php on line 895"
But that is a PHP bug. *sigh*
|
By: John Nilsson
Date: 2006-07-20
Time: 14:32
|
Re: ArrayAccess and ArrayObject "arrays" and tbs
Sorry, the patch should be the other way around ofcourse
|
By: John Nilsson
Date: 2006-07-20
Time: 15:04
|
Re: ArrayAccess and ArrayObject "arrays" and tbs
This works a little better:
--- tbs_class_php5.php 2006-06-25 18:33:22.000000000 +0200
+++ tbs.php 2006-07-20 15:01:38.000000000 +0200
@@ -899,6 +899,14 @@
if (!isset($Loc->PrmLst['noerr'])) $this->meth_Misc_Alert($Loc,'item \''.$x.'\' is not an existing key in the array.',true);
unset($Value); $Value = ''; break;
}
+ } elseif ($Value instanceof ArrayAccess) {
+ if ( $Value->offsetExists($x) ) {
+ $newVal = $Value->offsetGet($x);
+ unset($Value); $Value = $newVal;
+ } else {
+ if (!isset($Loc->PrmLst['noerr'])) $this->meth_Misc_Alert($Loc,'item \''.$x.'\' is not an existing key in the array.',true);
+ unset($Value); $Value = ''; break;
+ }
} elseif (is_object($Value)) {
$ArgLst = tbs_Misc_CheckArgLst($x);
if (method_exists($Value,$x)) {
|
By: Skrol29
Date: 2006-07-20
Time: 15:18
|
Re: ArrayAccess and ArrayObject "arrays" and tbs
Something like the following should work too.
But doing this, you avoid any access to other methods of ArrayAccess objects from the template. This can be enhanced, for example, by addind [] around the offset value in order to tell it's an offset value to get.
} elseif (is_object($Value)) {
++ if ($Value instanceof ArrayAccess) {
++ $x =& $Value->offsetGet($x);
++ } else {
$ArgLst = tbs_Misc_CheckArgLst($x);
if (method_exists($Value,$x)) {
$x = call_user_func_array(array(&$Value,$x),$ArgLst);
} elseif (property_exists($Value,$x)) {
$x =& $Value->$x;
} else {
if (!isset($Loc->PrmLst['noerr'])) $this->meth_Misc_Alert($Loc,'item '.$x.'\' is neither a method nor a property in the class \''.get_class($Value).'\'.',true);
unset($Value); $Value = ''; break;
}
++ }
$Value =& $x; unset($x); $x = '';
|
|
By: John Nilsson
Date: 2006-07-20
Time: 18:00
|
Re: ArrayAccess and ArrayObject "arrays" and tbs
I'm working on a slight modification.
Dilemma: If (substr($x,-1,1)!==')') && offsetExists($x) && method_exists($x) ... which takes precedence?
I guess it's intentional that the current semantics treats x.y() the same as x.y
I suggest that x.y should fail if y is not a property or a valid offset, like this:
} elseif (is_object($Value)) {
if (substr($x,-1,1)===')') {
$ArgLst = tbs_Misc_CheckArgLst($x);
if (method_exists($Value,$x)) {
$x = call_user_func_array(array(&$Value,$x),$ArgLst);
} else {
if (!isset($Loc->PrmLst['noerr'])) $this->meth_Misc_Alert($Loc,'item '.$x.'\' is not a method in the class \''.get_class($Value).'\'.',true);
unset($Value); $Value = ''; break;
}
} else {
if ($Value instanceof ArrayAccess && $Value->offsetExists($x)) {
$x =& $Value->offsetGet($x);
} elseif (property_exists($Value,$x)) {
$x =& $Value->$x;
} elseif ($Value instanceof ArrayAccess) {
if (!isset($Loc->PrmLst['noerr'])) $this->meth_Misc_Alert($Loc,'item \''.$x.'\' is neither an existing arraykey nor a property in the class \''.get_class($Value).'\'.',true);
unset($Value); $Value = ''; break;
} else {
if (!isset($Loc->PrmLst['noerr'])) $this->meth_Misc_Alert($Loc,'item '.$x.'\' is not a property in the class \''.get_class($Value).'\'.',true);
unset($Value); $Value = ''; break;
}
}
$Value =& $x; unset($x); $x = '';
|
|
By: Skrol29
Date: 2006-07-20
Time: 18:26
|
Re: ArrayAccess and ArrayObject "arrays" and tbs
> ... which takes precedence?
In case of series of expressions separated by AND, PHP proceeds from left to right and breaks as soon as a false expression is met, without evaluating next ones. I hope this answer your question.
There is a problem with your upgraded version for TBS tags. If you do :
(having $AccObj as an AccessObject variable)
And if 'count' is an existing setoff, then it will display $AccObj->setoffGet('count'), and makes $AccObj->count unreachable.
And that will be the same for all properties and methods of an AccessObject variable.
|
By: John Nilsson
Date: 2006-07-20
Time: 18:53
|
Re: ArrayAccess and ArrayObject "arrays" and tbs
Actually, that was the purpose of my first question. How should this dilemma be solved? I allready knew th precedence rules of the &&-operator ;)
I can't se anyway to solve this dilemma without introducing some new syntax rules for tbs. My version means
given x.y, y will never be treated as a method
if y is both an arraykey offset, and a property, the arraykey offset takes precedence.
Rationale: If y is a property, there is a fair chance that that property is reference by offsetGet, maybe with som additional logic, so prefer offsetGet.
|
|
Posting in progress.
Please wait...
|