PHP - 有没有办法区分何时通过PHP构造调用魔术方法或直接?

in PHP, is there is there a way to differentiate when magic method is called through a PHP construct or directly?

E.g.: public function __clone() {} is called each time an object is cloned through the clone keyword:

$a = new ObjectA();
$clone = clone $a; // Calls __clone()

However, someone can even (do not know why someone should do that, but, anyway) call __clone() directly:

$a = new ObjectA();
$clone = $a->__clone(); // Call __clone() directly

Same goes for other PHP magic methods (__call(), __debugInfo, etc.).

Can we differentiate between the two cases somehow?

Thank you for the attention!

EDIT: Assume the following scenario:

I have a dynamic proxy class, which extends a base class and internally creates an instance of the base class only when the object is effectively used:

class A {
   ...
   public function __clone() {
      echo "clone A!!!";
   }
   ...
}

class DynamicProxy extends A {

   protected $a = NULL;

   public function __clone() {
      $this->createA();
      if ( /* __clone() is triggered by `clone $obj`, I need to clone $a: */ )  {
        clone $this->a;
      }
      else {
        // But if someone, for some reason (I do not now why, but it could be, and I would like to be consistent), have called `$obj->__clone();`, I do not have to call `clone $obj`, but proxy the call:
        return $this->a->__clone();
      }

   }

   protected function createA() {
      if (is_null($this->a)) {
        $this->a = new A();
      }
   }
}

$obj = new DynamicProxy();

Many of your assumptions are incorrect, one can not call __clone() directly and get a clone of the object to be returned because the docs says:

void __clone ( void )

and

An object's __clone() method cannot be called directly.

It is a bit misleading because it can actually be called, but the result is like calling any other object's method, and will not make a clone of the original object.

Consider this snippet:

<?php
class Foo {
    function __construct($x) {
        $this->x = $x;
    }

    function __clone() {
        echo "I'm a clone";
    }

    function getX() {
        echo $this->x;
    }
}

$a = new Foo('foo');
$b = $a->__clone(); # > I'm a clone
var_dump($b);       # > NULL
$b->getX();         # Exception: Call to a member function getX() on null

?> 

__clone method is called on newly created, clone object after it has been cloned. It's more like a callback and it does not produce a clone.

Maybe it would be better if PHP threw an exception when someone tried to call __clone directly, but there are many things PHP could do better.

What you can do is to deeply test if what you think is possible is really possible.