Working to implement Getter/Setter Accessor syntax as per https://wiki.php.net/rfc/propertygetsetsyntax but brand new to php internals development.
I was planning on having the parser define methods on the class for the getter/setter such as __getHours() and __setHours() and then have those functions called in leiu of __get() if they are defined, does that seem like a reasonable strategy for this?
More specific problems on the parser side of things, here is what I have now:
getter_setter_declarations:
getter_declaration
setter_declaration
| setter_declaration
getter_declaration
| setter_declaration
| getter_declaration
| /* empty */
;
getter_declaration:
method_modifiers T_GET
{ zend_do_begin_function_declaration(&$2, &$$, 1, ZEND_RETURN_VAL, &$1 TSRMLS_CC); }
'{' inner_statement_list '}'
{ /******** $$ != Hours Here!! ***************/
zend_do_abstract_method(&$$, &$1, &$4 TSRMLS_CC); zend_do_end_function_declaration(&$2 TSRMLS_CC); }
setter_declaration:
T_SET '{' inner_statement_list '}'
class_variable_declaration:
T_VARIABLE
{ $$ = $1; /**** Capture variable name ****/ } '{' getter_setter_declarations '}'
| class_variable_declaration ',' T_VARIABLE
{ zend_do_declare_property(&$3, NULL, CG(access_type) TSRMLS_CC); }
| class_variable_declaration ',' T_VARIABLE
'=' static_scalar { zend_do_declare_property(&$3, &$5, CG(access_type) TSRMLS_CC); }
| T_VARIABLE
{ zend_do_declare_property(&$1, NULL, CG(access_type) TSRMLS_CC); }
| T_VARIABLE
'=' static_scalar { zend_do_declare_property(&$1, &$3, CG(access_type) TSRMLS_CC); }
;
I'm just working on the getter now.
- I am able to get the
T_VARIABLE
name passed through to the zend_do_begin_function() using $$ however $$ is no longer correctly set by zend_do_abstract_method(). What would be a more appropriate way to store the variable znode? I see there are a number of stacks in the compiler_globals, would using one of those or creating a new one be appropriate?
1.1) Alternatively to #1, is there a way to access the T_VARIABLE
znode from the zend_do_begin_function_declaration() line? (Reach re patterns from previous/prior matches/lines)
-
I am having trouble with building the function name (2nd param to zend_do_begin_function) since that function needs to have a znode as the input. I could stuff code in here to concat the strings together and build a znode but since there is sparsely any real code in this file I hesitate to do so. Any recommendations here?
-
An interesting situation with the above code is that the function is declared and is seen through a ReflectionClass() but calling it indicates that the function does not exist, I think that is because $$ was cleared/changed by the time zend_do_abstract() is called, is this something I should add a check for? (Calling zend_do_abstract() with a function name that was not previously seen via zend_do_begin_function_declaration())
For reference, here is the PHP test class I am using:
#!/opt/trunk/sapi/cli/php
<?php
class TimePeriod {
public $Seconds;
public function __construct($Seconds) {
$this->Seconds = $Seconds;
}
public $Hours {
get {
return $this->Seconds / 3600;
}
/* set { $this->Seconds = $value * 3600; } // The variable $value holds the incoming value to be "set"*/
};
}
$o = new TimePeriod(3600);
echo $o->Seconds."\r\n";
echo $o->Hours()."\r\n";
?
Hi,
quick note: By introducing T_GET and T_SET, you disable people the
ability to name any function/method "set" or "get", which I'm sure
many people used. You should rather keep to T_STRING
and check it's
value.
Best,
Working to implement Getter/Setter Accessor syntax as per https://wiki.php.net/rfc/propertygetsetsyntax but brand new to php internals development.
I was planning on having the parser define methods on the class for the getter/setter such as __getHours() and __setHours() and then have those functions called in leiu of __get() if they are defined, does that seem like a reasonable strategy for this?
More specific problems on the parser side of things, here is what I have now:
getter_setter_declarations:
getter_declaration
setter_declaration
| setter_declaration
getter_declaration
| setter_declaration
| getter_declaration
| /* empty */
;getter_declaration:
method_modifiers T_GET
{ zend_do_begin_function_declaration(&$2, &$$, 1, ZEND_RETURN_VAL, &$1 TSRMLS_CC); }
'{' inner_statement_list '}'
{ /******** $$ != Hours Here!! ***************/
zend_do_abstract_method(&$$, &$1, &$4 TSRMLS_CC); zend_do_end_function_declaration(&$2 TSRMLS_CC); }setter_declaration:
T_SET '{' inner_statement_list '}'class_variable_declaration:
T_VARIABLE { $$ = $1; /**** Capture variable name ****/ } '{' getter_setter_declarations '}'
| class_variable_declaration ','T_VARIABLE
{ zend_do_declare_property(&$3, NULL, CG(access_type) TSRMLS_CC); }
| class_variable_declaration ','T_VARIABLE
'=' static_scalar { zend_do_declare_property(&$3, &$5, CG(access_type) TSRMLS_CC); }
|T_VARIABLE
{ zend_do_declare_property(&$1, NULL, CG(access_type) TSRMLS_CC); }
|T_VARIABLE
'=' static_scalar { zend_do_declare_property(&$1, &$3, CG(access_type) TSRMLS_CC); }
;I'm just working on the getter now.
1) I am able to get the
T_VARIABLE
name passed through to the zend_do_begin_function() using $$ however $$ is no longer correctly set by zend_do_abstract_method(). What would be a more appropriate way to store the variable znode? I see there are a number of stacks in the compiler_globals, would using one of those or creating a new one be appropriate?1.1) Alternatively to #1, is there a way to access the
T_VARIABLE
znode from the zend_do_begin_function_declaration() line? (Reach re patterns from previous/prior matches/lines)
I am having trouble with building the function name (2nd param to zend_do_begin_function) since that function needs to have a znode as the input. I could stuff code in here to concat the strings together and build a znode but since there is sparsely any real code in this file I hesitate to do so. Any recommendations here?
An interesting situation with the above code is that the function is declared and is seen through a ReflectionClass() but calling it indicates that the function does not exist, I think that is because $$ was cleared/changed by the time zend_do_abstract() is called, is this something I should add a check for? (Calling zend_do_abstract() with a function name that was not previously seen via zend_do_begin_function_declaration())
For reference, here is the PHP test class I am using:
#!/opt/trunk/sapi/cli/php
<?php
class TimePeriod {public $Seconds;
public function __construct($Seconds) {
$this->Seconds = $Seconds;
}
public $Hours {
get {
return $this->Seconds / 3600;
}
/* set { $this->Seconds = $value * 3600; } // The variable $value holds the incoming value to be "set"*/
};
}$o = new TimePeriod(3600);
echo $o->Seconds."\r\n";
echo $o->Hours()."\r\n";?>
--
--
Etienne Kneuss
http://www.colder.ch
2011/11/8 Clint M Priest cpriest@zerocue.com
echo $o->Hours()."\r\n";
Why use as method call? Why not "echo $o->Hours;" ?
With regards, Alexander Moskaliov
Irker@irker.net
In this particular case I was just trying to see if Hours() had properly been defined as a callable function. Eventually that function name would become __getHours(), this particular line was just a test (which is where I discovered that the $$ was no longer set to ‘Hours’ on the zend_do_abstract_method())
From: Александр Москалёв [mailto:irker@irker.net]
Sent: Tuesday, November 08, 2011 2:04 PM
To: Clint M Priest
Cc: internals@lists.php.net
Subject: Re: [PHP-DEV] Accessors Parsing
2011/11/8 Clint M Priest <cpriest@zerocue.commailto:cpriest@zerocue.com>
echo $o->Hours()."\r\n";
Why use as method call? Why not "echo $o->Hours;" ?
With regards, Alexander Moskaliov
Irker@irker.net<mailto:Irker@irker.net