Определение методов класса в PHP

Возможно ли в PHP (as it is in C++) объявить class method OUTSIDE class definition?

Нет, начиная с PHP 5.2. Тем не менее, вы можете использовать метод __call magic для переадресации вызова произвольной функции или метода.

 class A { public function __call($method, $args) { if ($method == 'foo') { return call_user_func_array('bar', $args); } } } function bar($x) { echo $x; } $a = new A(); $a->foo('12345'); // will result in calling bar('12345') 

В PHP 5.4 поддерживается поддержка признаков . Trait – это реализация метода (методов), который не может быть создан как отдельный объект. Вместо этого, черта может использоваться для расширения класса с сохраненной реализацией. Подробнее читайте здесь .

Да, после его определения можно добавить метод в класс PHP. Вы хотите использовать classkit , который является «экспериментальным» расширением. По-видимому, это расширение не включено по умолчанию, однако, это зависит от того, можно ли скомпилировать пользовательский PHP-файл или загрузить PHP-библиотеки DLL, если на окнах (например, Dreamhost позволяет создавать собственные двоичные файлы PHP, и их довольно легко настроить ).

 <?php class A { } classkit_method_add('A', 'bar', '$message', 'echo $message;', CLASSKIT_ACC_PUBLIC); $a = new A(); $a->bar('Hello world!'); 

Пример из руководства PHP:

 <?php class Example { function foo() { echo "foo!\n"; } } // create an Example object $e = new Example(); // Add a new public method classkit_method_add( 'Example', 'add', '$num1, $num2', 'return $num1 + $num2;', CLASSKIT_ACC_PUBLIC ); // add 12 + 4 echo $e->add(12, 4); 

Возможно, вы можете переопределить __call или __callStatic, чтобы найти отсутствующий метод во время выполнения, но вам нужно будет создать свою собственную систему для поиска и вызова кода. Например, вы можете загрузить класс «Делегат» для обработки вызова метода.

Вот пример: если вы попытались вызвать $ foo-> bar (), класс попытался создать класс FooDelegate_bar и bar () на нем с теми же аргументами. Если у вас установлена ​​автоматическая загрузка классов, делегат может жить в отдельном файле до тех пор, пока вам не понадобится …

 class Foo { public function __call($method, $args) { $delegate="FooDelegate_".$method; if (class_exists($delegate)) { $handler=new $delegate($this); return call_user_func_array(array(&$handler, $method), $args); } } } 

Нет.

Вы можете расширить ранее объявленные классы, хотя, если это поможет.

Поскольку PHP 5.3 поддерживает закрытие, вы можете динамически определять методы экземпляра в качестве переменных, удерживающих замыкания:

 $class->foo = function (&$self, $n) { print "Current \$var: " . $self->var . "\n"; $self->var += $n; print "New \$var: " .$self->var . "\n"; }; 

Принимая $self (вы не можете использовать $this вне контекста объекта) в качестве ссылки ( & ), вы можете изменить экземпляр.

Однако при попытке вызвать функцию обычно возникают проблемы:

 $class->foo(2); 

Вы получаете фатальную ошибку. PHP считает, что foo – это метод $class из-за синтаксиса. Кроме того, вы должны передать экземпляр в качестве первого аргумента.

К счастью, существует специальная функция для вызова функций по имени call_user_func :

 call_user_func($class->foo, &$class, 2); # => Current $var: 0 # => New $var: 2 

Не забудьте поставить & перед переменной экземпляра.

Что еще проще, если вы используете метод __call magic:

 class MyClass { public function __call ($method, $arguments) { if (isset($this->$method)) { call_user_func_array($this->$method, array_merge(array(&$this), $arguments)); } } } 

Теперь вы можете вызвать $class->foo(2) . Метод magic __call ловит вызов неизвестного метода и вызывает замыкание в переменной $class->foo с тем же именем, что и вызываемый метод.

Конечно, если $class->var был закрытым, закрытие в переменной $class->foo не получило бы доступа к нему.

Нет, это невозможно. если вы определяете функцию / метод вне класса, она становится глобальной функцией.

C ++ тоже не может этого сделать. Вы смешивали декларацию с дефиницией ?

Нет, как говорили все, это не совсем возможно.

Однако вы можете сделать что-то подобное, чтобы эмулировать mixin в PHP или добавлять методы в класс во время выполнения, что примерно так же близко, как вы собираетесь получить. В основном, это просто использование шаблонов проектирования для достижения той же функциональности. Zope 3 делает что-то похожее на эмуляцию mixins в Python, другой язык, который не поддерживает их напрямую.