nixischev
@nixischev
PHP backend developer

Как сделать «магические» методы в PHP?

Нужно сделать возможность вызова свойств класса через "магические" методы (к примеру, как вызов свойств моделей в Magento)

Пример:
у класса MyClass есть свойство awesome_data, нужно сделать "магический" метод для вызова этого свойства: MyClass::getAwesomeData() и для установки этого свойства: MyClass::setAwesomeData()

Как это можно сделать?

pS: свойств у класса может быть любой количество и называться они могут по разному, но методы вручную для них не должны прописываться.

ppS: лучший пример - вызов данных из модели в Magento
  • Вопрос задан
  • 2342 просмотра
Решения вопроса 1
KorsaR-ZN
@KorsaR-ZN
То, что Вам нужно...
class MyClass
{

   public function __call($method = null, $data = null)
   {
	   $parts = preg_split('/([A-Z][^A-Z]*)/', $method, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
	   $type  = array_shift($parts);
	
	   if ($type != 'get' && $type != 'set') {
		   return;
	   }
	
       $varName = strtolower(implode('_', $parts));

       switch ($type) {
           case 'set' :
               $this->$varName = $data;
           break;
		
           case 'get': 
              return isset($this->$varName) ? $this->$varName : null;
           break;
        }
	
	   return;
    }
}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
Melkij
@Melkij
PostgreSQL DBA
А в чём проблема-то?
Про магические методы вы, очевидно, уже слышали.
Ответ написан
<?php

	class MyClass {

		private
			$data = array();

		public function __construct() {
			$this->data = array(
				'test' 	=> 'data test',
				'test2'	=> 'data test 2'
			);
		}

		public function __call( $method = null, $data = null ){
			$type = strtolower( substr( $method, 0, 2 ) );
			switch( type ) {
				case 'set': {
					$this->data[strtolower( substr( $method, 3 ) )] = $data;
					break;
				}
				case 'get': {
					$key = strtolower( substr( $method, 3 ) );
					return isset( $this->data[$key] ) ? $this->data[$key] : null;
					break;
				}
			}
			return null;
		}

	}

	$object = new MyClass();

	print $object->getTest(); // data test
	print $object->getTest2(); // data test 2

	$object->setFoo( 'bar' );

	print $object->getFoo(); // bar
	print $object->getFoo2(); // null

P.S. не тестил
P.S. 2 дико прошу прощения :) вообще не понимал что пишу.. конец рабочего дня как ни как.
Ответ написан
mlnkv
@mlnkv
JavaScript Developer
class Test {

	static $data = array();
	
	public static function __callStatic($name, $params) {

		$propName = substr($name, 3);

		if (substr($name, 0, 3) == "set") {
			return static::$data[$propName] = $params[0];		
		}				
		return static::$data[$propName];
	}
}


Test::setMyName("Bob");
Test::getMyName(); //Bob
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы