php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Thanks for voting! Your vote should be reflected in the statistics below.
Bug #66331 ZEND_SEND_PREFER_REF issue trying to overlad
Submitted: 2013-12-20 14:46 UTC Modified: 2021-07-23 10:23 UTC
Votes:81
Avg. Score:4.7 ± 0.6
Reproduced:78 of 78 (100.0%)
Same Version:26 (33.3%)
Same OS:38 (48.7%)
From: remi@php.net Assigned:
Status: Wont fix Package: *General Issues
PHP Version: 5.5.7 OS: irrevelant
Private report: No CVE-ID: None
 [2013-12-20 14:46 UTC] remi@php.net
Description:
------------
When trying to overload a class, with function where parameters have ZEND_SEND_PREFER_REF

Ex : Memcached::get() in version 2.2.0b1

ZEND_BEGIN_ARG_INFO_EX(arginfo_get, 0, 0, 1)
	ZEND_ARG_INFO(0, key)
	ZEND_ARG_INFO(0, cache_cb)
	ZEND_ARG_INFO(2, cas_token)
	ZEND_ARG_INFO(1, udf_flags)
ZEND_END_ARG_INFO()


Real use case: try to mock the class using PHPUnit for test suite.

See https://github.com/symfony/symfony/issues/9797

Test script:
---------------
<?php
class MyMemcached extends memcached {
        public function get($key, $cache_cb = NULL, &$cas_token = NULL, &$udf_flags = NULL) {
        }
}


Expected result:
----------------
No error.


Actual result:
--------------
Strict standards: Declaration of MyMemcached::get() should be compatible with
Memcached::get($key, $cache_cb = NULL, &$cas_token = NULL, &$udf_flags = NULL)
in /tmp/foo.php on line 5


Patches

pass-by-ref-proto-check.patch (last revision 2013-12-20 17:56 UTC by remi@php.net)
pass-by-ref-recv-init.patch (last revision 2013-12-20 16:06 UTC by krakjoe@php.net)

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-12-20 16:06 UTC] krakjoe@php.net
The following patch has been added/updated:

Patch Name: pass-by-ref-recv-init.patch
Revision:   1387555590
URL:        https://bugs.php.net/patch-display.php?bug=66331&patch=pass-by-ref-recv-init.patch&revision=1387555590
 [2013-12-20 17:04 UTC] rdlowrey@php.net
Just tested krakjoe's patch -- works for me.
 [2013-12-20 17:56 UTC] remi@php.net
The following patch has been added/updated:

Patch Name: pass-by-ref-proto-check.patch
Revision:   1387562184
URL:        https://bugs.php.net/patch-display.php?bug=66331&patch=pass-by-ref-proto-check.patch&revision=1387562184
 [2013-12-20 17:59 UTC] remi@php.net
@krackjoe, thanks, but with your patch applied on 5.5.7, this doesn't change the result of provided case.

A simple fix, see "pass-by-ref-proto-check.patch" just make zend_do_perform_implementation_check a little less strict, and consider pass_by_reference as a boolean (so consider 1 and 2 as equivalent, for the proto check).
 [2013-12-20 19:29 UTC] krakjoe@php.net
the patch is correct, what is not correct is the arg info in memcached extension.

however, it is not currently possible to write the arginfo with the current macros, the correct arginfo as it is expected is:

ZEND_BEGIN_ARG_INFO_EX(arginfo_get, 0, 0, 1)
	ZEND_ARG_INFO(0, key)
	{ "cache_cb", sizeof("cache_cb")-1, NULL, 0, 0, 1, 0},
	{ "cas_token", sizeof("cas_token")-1, NULL, 0, 0, 1, 2},
	{ "udf_flags", sizeof("udf_flags")-1, NULL, 0, 0, 1, 2}
ZEND_END_ARG_INFO()

To hide the symptoms is not enough, the arg_info must reflect what is actually required, it should be parsed, and have a way to be specified in C correctly.
 [2013-12-20 19:33 UTC] krakjoe@php.net
Here is some test code that shows the patch to compiler is correct:

http://pastebin.com/VFjwL0bv

You can make that error in the way you expect, if the prototype does not match exactly.
 [2013-12-21 05:39 UTC] datibbaw@php.net
Tested krakjoe's patch as well with the following result:

string(33) "ConcreteInNature::methodByRefInit"
 [2014-10-09 15:53 UTC] mkoppanen@php.net
@krakjoe: Is there anything preventing the patch you provided to be merged?
 [2021-07-23 10:23 UTC] nikic@php.net
-Status: Open +Status: Wont fix
 [2021-07-23 10:23 UTC] nikic@php.net
As we don't support this passing mode for userland code, it's not possible to inherit from such a method while being compatible -- you'll always introduce incorrect behavior either for value or references.

Do not use PREFER_REF on non-final methods.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 14 05:01:29 2024 UTC