# Parameter checking in 5.2

- Thread: https://externals.io/message/25774
- Original archive: https://news-web.php.net/php.internals/25774
- Started by Christian Schneider on 2006-09-20T19:11:27+00:00
- Messages: 5
- 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

---

## #25774 — Christian Schneider — 2006-09-20T19:11:27+00:00

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

In the discussion about parameter checking in 5.2 I proposed to relax
the checks a tiny little bit: Don't test static functions (e.g. useful
for factory methods) and allow adding default values to functions (the
object of the inherited class still accepts the same parameters as the
base class). A patch is attached.

Example:
class Base
{
static function factory($x) { }
function foo($x) { }
}

class Spezialized extends Base
{
static function factory() { }	# Static method, e.g. factory method
function foo($x = null) { }	# Default values for specialized class
}

Regards,
- Chris

---

## #25779 — Jasper Bryant-Greene — 2006-09-21T02:00:10+00:00

URL: https://externals.io/message/25774#25779 · In reply to: #25774

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

+1

Given that static methods apply to the class and don't have much in the
way of inheritance rules, Christian's suggested behaviour makes a lot of
sense.

Jasper

Christian Schneider wrote:
> In the discussion about parameter checking in 5.2 I proposed to relax
> the checks a tiny little bit: Don't test static functions (e.g. useful
> for factory methods) and allow adding default values to functions (the
> object of the inherited class still accepts the same parameters as the
> base class). A patch is attached.
> 
> Example:
> class Base
> {
> static function factory($x) { }
> function foo($x) { }
> }
> 
> class Spezialized extends Base
> {
> static function factory() { }	# Static method, e.g. factory method
> function foo($x = null) { }	# Default values for specialized class
> }
> 
> Regards,
> - Chris
> 
> 
> ------------------------------------------------------------------------
> 
> Index: Zend/zend_compile.c
> ===================================================================
> RCS file: /repository/ZendEngine2/zend_compile.c,v
> retrieving revision 1.647.2.27.2.18
> diff -u -r1.647.2.27.2.18 zend_compile.c
> --- Zend/zend_compile.c	19 Sep 2006 21:36:53 -0000	1.647.2.27.2.18
> +++ Zend/zend_compile.c	20 Sep 2006 19:05:43 -0000
> @@ -1922,13 +1922,12 @@
>  	}
>  
>  	/* Checks for constructors only if they are declared in an interface */
> -	if ((fe->common.fn_flags & ZEND_ACC_CTOR) && !(proto->common.scope->ce_flags & ZEND_ACC_INTERFACE)) {
> +	if ((fe->common.fn_flags & (ZEND_ACC_CTOR | ZEND_ACC_STATIC)) && !(proto->common.scope->ce_flags & ZEND_ACC_INTERFACE)) {
>  		return 1;
>  	}
>  
>  	/* check number of arguments */
> -	if (proto->common.required_num_args != fe->common.required_num_args
> -		|| proto->common.num_args > fe->common.num_args) {
> +	if (proto->common.num_args > fe->common.num_args) {
>  		return 0;
>  	}
>  
> 
> 

- --
Jasper Bryant-Greene
Director
Album Limited

jasper@album.co.nz
+64 21 708 334 / 0800 425 286
http://www.album.co.nz/
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5-ecc0.1.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iFcDBQFFEfIqnqZ4vwo6v1gRCrP0AP4iqczaBXNYGTtooXvP8AKcfwS1tlfHghVa
U4EWSFsIMQD/eoAnLN9JeJaqFqIqfttF2Pq4TR1GLHkJdowFKZY7vgc=
=DSys
-----END PGP SIGNATURE

---

## #25784 — Marcus Boerger — 2006-09-21T14:46:13+00:00

URL: https://externals.io/message/25774#25784 · In reply to: #25774

Hello Christian,

  the short form is, use interfaces. And the long form is read the upgrade
  file and find out to use interfaces :-)

best regards
marcus

Wednesday, September 20, 2006, 12:11:27 PM, you wrote:

> In the discussion about parameter checking in 5.2 I proposed to relax
> the checks a tiny little bit: Don't test static functions (e.g. useful
> for factory methods) and allow adding default values to functions (the
> object of the inherited class still accepts the same parameters as the
> base class). A patch is attached.

> Example:
> class Base
> {
> static function factory($x) { }
> function foo($x) { }
> }

> class Spezialized extends Base
> {
> static function factory() { }   # Static method, e.g. factory method
> function foo($x = null) { }     # Default values for specialized class
> }

> Regards,
> - Chris



Best regards,
 Marcus

---

## #25835 — Christian Schneider — 2006-09-26T11:41:20+00:00

URL: https://externals.io/message/25774#25835 · In reply to: #25784

Marcus Boerger wrote:
>   the short form is, use interfaces. And the long form is read the upgrade
>   file and find out to use interfaces :-)

I don't understand how interfaces are connected to my proposal, please
explain.

Personally I don't need the strict OO checks for matching parameter
lists at all, but as long as they are `E_STRICT` (or the like) I have no
problem with them being done. Nevertheless I would like to relax them
just a tiny  little bit for signature changes not having an impact of
object compatibility.

That's why I posted two use cases where the checks IMHO go too far and
added a patch to change that.

Copy of my message:

> > […]
> 
> > […]
> 
> > […]

- Chris

---

## #25838 — Stanislav Malyshev — 2006-09-26T19:46:43+00:00

URL: https://externals.io/message/25774#25838 · In reply to: #25835

> Personally I don't need the strict OO checks for matching parameter
> lists at all, but as long as they are `E_STRICT` (or the like) I have no
> problem with them being done. Nevertheless I would like to relax them
> just a tiny  little bit for signature changes not having an impact of
> object compatibility.

I agree that allowing to extend method signature (albeit with notice) is 
a good thing. You could do a number of nice things with it like flexible 
interfaces receiving variable parameters - still staying with OO. E.g., 
you can do patterns like this:

abstract class Processor() {
abstract protected function process();
private function prepare() { /// do something }
public function prepare_and_process(/* variable args */) {
   $this->prepare();
   $this->process(/* some args */);
}
}

And extends it overriding only process() function having concrete 
arguments. Of course, not everybody wants it - some would miss strict 
control on process parameters - but I don't see why it should not be 
possible in PHP, for those who wants it. That's why PHP is a dynamic 
language, I think. Right now if I remove abstract from process() method 
I can do it - but why couldn't I do it with abstract too?

Interfaces don't exactly play nice with it since you can not add code to 
the interface and can not define visibility for methods.
