|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #63834 Add a function to detect a methods calling context
Submitted: 2012-12-22 15:46 UTC Modified: 2020-10-23 16:08 UTC
Avg. Score:4.0 ± 0.8
Reproduced:4 of 4 (100.0%)
Same Version:4 (100.0%)
Same OS:3 (75.0%)
From: tolan333 at gmail dot com Assigned:
Status: Suspended Package: Class/Object related
PHP Version: Irrelevant OS: Any
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2012-12-22 15:46 UTC] tolan333 at gmail dot com
Currently it is hard to get to know the exact context from which a method is called from. Sure, there is debug_backtrace and the Reflection API, but these are no ideal nor complete and reliable solutions.

I suggest to introduce a new function: get_calling_context (similar to get_calling_class).

A possible use-case is shown below

Possible return values could be:

const PHP_CONTEXT_PRIVATE = ?, // Method was called from the class it is defined in.
      PHP_CONTEXT_INHERITED = ?, // Method was called from a class inheriting the defining class.
      PHP_CONTEXT_EXTERN_USER = ?, // Method was called from outside the class, but in userland code
      PHP_CONTEXT_EXTERN_CORE = ?; // Method was called from outside, but was used as callback (Session handler, error handler, any predefined function awaiting a callback

Use case:
Currently I use virtual properties (via __get and __set) to validate and manipulate properties data while still keeping the ability to iterate over the entire object(implementing IteratorAggregate). This allows me also to have different visibility states for accessors (which will hopefully be supported in 5.5 without having to rely on custom implementations) but not for the properties themself.

Simplified __set implementation:
    public function __set($name, $value)
        // called from wrong context
        if (\property_exists($this, $name)) {
            if (\method_exists($this, 'set' . \ucfirst($name))) {
                return $this->{'set' . \ucfirst($name)}($value);
            } else {
                throw new WritePropertyFromWrongContextException("virtual property $name can not be accessed from this context");
        } elseif (\method_exists($this, 'set' . \ucfirst($name))) {
            return $this->{'set' . \ucfirst($name)}($value);
        } elseif ($this->objectConfiguration['accessMapAsProps'] == true && $this->offsetExists($name)) {
            $this[$name] = $this->createPropertyValidator($name)->validate($value,$this->getRuleSet()[$name])->getValidatedValue();
        } else {
            throw new WriteNonExistingPropertyException("Virtual property \$$name does not exist in class " .

There is no possibility to react on different scenarios as there can be only one __set which is either public,protected or private. There is no option to implement different behaviors for different visibility.

Another usecase is the usage of object callbacks in handlers like

For example the write callback does not (per documentation) output data. However in debug scenarios and in unit-tests it would be ideal to know if the method was called from the core as a usual session handler or in a different scenario in usercode.

Additionally this would go inline with already existing functions like get_called_class, get_parent_class and partly get_class.


63834-2.patch (last revision 2012-12-31 11:49 UTC by
63834.patch (last revision 2012-12-31 11:11 UTC by

Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2012-12-31 11:11 UTC]
The following patch has been added/updated:

Patch Name: 63834.patch
Revision:   1356952314
 [2012-12-31 11:19 UTC]
I think it makes sense to provide the scope which calls a method. Beyond this is 
application specific, I have suggested a patch that provides the name like the 
associated methods.
 [2012-12-31 11:36 UTC]
The following patch has been added/updated:

Patch Name: 63834-2.patch
Revision:   1356953808
 [2012-12-31 11:37 UTC]
-2 will provide get_calling_method and get_calling_class, I think that's 
everything you should need
 [2012-12-31 11:49 UTC]
The following patch has been added/updated:

Patch Name: 63834-2.patch
Revision:   1356954599
 [2012-12-31 11:55 UTC]
I still fail to use just what exactly this asks for and how it would be beneficial.

@krakjoe: The get_calling_method and get_calling_class functions you added should already be fully covered by debug_backtrace, so I see little value in adding them (as the use case is rather limited).

@op: Regarding the last two PHP_CONTEXT_EXTERN constants, what do you mean by "user" and "core"? E.g. if you invoke a callback using call_user_func, is that an internal or a userland call? It's the internal function doing the call, but it's really the user who triggers it. I don't see how these constants would carry any meaning.

The other two again can be covered by debug_backtrace, can't they? Just get the class of the call and check whether it equals __CLASS__ (=> private) or is a subclass of __CLASS__ (=> protected) or is none (=> public). Seems simple enough to me.
 [2012-12-31 12:02 UTC]
acquiring a backtrace is an inefficient means of obtaining this information ...
 [2013-05-21 08:10 UTC] tolan333 at gmail dot com
Thanks for the comments. After rethinking about this, krakjoe's suggestions seems to be superior (solves the issue and is way easier). Is their any chance to see this improvement in 5.5 or 5.6? Or what needs to be done to get this implemented?
 [2020-10-23 16:08 UTC]
-Status: Open +Status: Suspended
 [2020-10-23 16:08 UTC]
> Or what needs to be done to get this implemented?

Since this feature is obviously controversial, and needs to be
discussed on the internals mailing list[1], so please forward the
feature request.  For the time being, I'm suspending this ticket.

[1] <>
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Wed Dec 02 10:01:24 2020 UTC