php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #75530 __callStatic precedence in non-static method invocation
Submitted: 2017-11-15 21:48 UTC Modified: 2018-12-26 16:16 UTC
From: msaladna at apisnetworks dot com Assigned:
Status: Not a bug Package: Class/Object related
PHP Version: 7.1.11 OS: Irrelevant
Private report: No CVE-ID: None
 [2017-11-15 21:48 UTC] msaladna at apisnetworks dot com
Description:
------------
According to the documentation, 
__callStatic() is triggered when invoking inaccessible methods in a static context.

If a method then is declared non-static with a __callStatic() handler in the class, accessing the method statically should route through __callStatic() instead of generating a fatal error as the method is inaccessible statically.

Test script:
---------------
<?php
	class Test
	{
		protected $root = '';

		public function __construct(string $root = '/')
		{
			$this->root = $root;
		}

		public static function bindTo(string $root = '/')
		{
			return new static($root);
		}

		public static function __callStatic($name, $arguments)
		{
			$instance = static::bindTo();
			return $instance->$name($arguments);
		}

		public function test() {
			return $this->root . '/foo';
		}
	}

	print Test::bindTo('/elsewhere')->test();
	print Test::test();

Expected result:
----------------
/elsewhere/foo
/foo

Actual result:
--------------
/elsewhere/foo
PHP Fatal error:  Uncaught Error: Non-static method Test::test() cannot be called statically

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-11-16 04:11 UTC] daniel at ciochiu dot ro
The problem is that method test is already implemented and it is public (smaller code: https://3v4l.org/Gd1ba). Php documentation refers to overloading logic (dynamically create properties and methods: http://php.net/manual/ro/language.oop5.overloading.php) as:
<The overloading methods are invoked when interacting with properties or methods that have not been declared or are not visible in the current scope. The rest of this section will use the terms "inaccessible properties" and "inaccessible methods" to refer to this combination of declaration and visibility.>

So, the test method is public.
If this method is changed to protected scope, you have the expected desire, which matches the documentation: https://3v4l.org/AUtBB
 [2018-12-26 16:16 UTC] jhdxr@php.net
-Status: Open +Status: Not a bug
 [2018-12-26 16:16 UTC] jhdxr@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

this is expected behavior, see daniel's explanation above.
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Wed Oct 28 09:01:28 2020 UTC