# Accessors Parsing

- Thread: https://externals.io/message/56164
- Original archive: https://news-web.php.net/php.internals/56164
- Started by Clint M Priest on 2011-11-08T14:26:44+00:00
- Messages: 4
- 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

---

## #56164 — Clint M Priest — 2011-11-08T14:26:44+00:00

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

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)

2)  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? 

3) 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";

?

---

## #56165 — Etienne Kneuss — 2011-11-08T16:52:01+00:00

URL: https://externals.io/message/56164#56165 · In reply to: #56164

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)
>
> 2)  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?
>
> 3) 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

---

## #56175 — irker@irker.net — 2011-11-08T20:04:02+00:00

URL: https://externals.io/message/56164#56175 · In reply to: #56164

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

---

## #56176 — Clint M Priest — 2011-11-08T22:01:54+00:00

URL: https://externals.io/message/56164#56176 · In reply to: #56175

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.com<mailto: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
