Pull to refresh

Перегрузка методов в php?

Reading time3 min
Views10K
Я учился программировать сначала на Java, затем подвернулась работа PHP программиста и я достаточно быстро на него пересел. Однако насколько вы можете знаеть Java — язык строгой типизации, а PHP нет, отсюда у меня появились некоторые проблемы с написанием некотрых классов.
Например в PHP нет явной перегрузки методов, я предлогаю обсудить как можно найти выход из такой сютуации.

Для примера рассмотрим класс продуктов допустим в интернет магазине.
class Prodcuts {
            public $name;
	public $price;
	public $id;
	function __construct($id){
		$sql = "SELECT * FROM products WHERE id =$id";
		$result = mysql_query($sql);
		$array  = mysql_fetch_array($result);
		$this->name = $array['name']; 
		$this->price = $array['price'];
		$this->id = $id; 
	}

}



Создать новый обьект в таком сулучае можно будет так:
$objProd = new Product(1)
В конструкторе класса выбиратся всё что связанно с id=1 и обьект инициализируется.
Но в какой то момент я понял мне требуется инициализация обьекта и по другим параметрам,
нариример для такого метода:
	static function create($name,$price){
		$sql = "INSERT INTO poducts(name,price) VALUES ('$name','$price')";
		if(mysql_query($sql)){
			return new Prodcuts($name,$price);
		}
	}



Тут родился вопрос перегрузки конструктора или какого то альтернативного способа инициализации обьекта.
Я знаю несколько способов и поделюсь ими свами. Буду рад если кто-то предложит ещё варианты решения этой задачи.

Cпособ №1. Использование опциональных параметров.
Переделам конструктор так:

	function __construct($id=null,$name=null,$price=null){
		if ( isset($name) && isset($price)){
			$this->name = $name;
			$this->price = $price;
		}else {
			$sql = "SELECT * FROM products WHERE id =$id";
			$result = mysql_query($sql);
			$array  = mysql_fetch_array($result);
			$this->name = $array['name']; 
			$this->price = $array['price'];
			$this->id = $id; 
		}
	}


тоесть мы можем не указывать параметр id
получается так:
$product = new Prodcuts(null,$name,$price);
согласитесь, это не очень красиво.

Cпособ №2. Использование функций func_num_args() и func_get_arg().


	function __construct($id){
		if(func_num_args()>1){
			$this->name = func_get_arg(0);
			$this->price = func_get_arg(1);
		}else{
			$sql = "SELECT * FROM products WHERE id =$id";
			$result = mysql_query($sql);
			$array  = mysql_fetch_array($result);
			$this->name = $array['name']; 
			$this->price = $array['price'];
			$this->id = $id; 
		}
	}
	


Здесь мы используем две «магические» функции:
func_num_args() — возвращает колличество аргументов текущей функции,
func_get_arg() — возвращает указанный аргумент текущей функции(отсчет ведётся с ноля),
проверяем колличество указанных параметров и инициализируем объект так как нам нужно.

Способ №3. Использования для инициализации статичной функции отказ от «перегрузки» конструкторов


static public function createWithTwoParams($name,$price) { 
    $object = new self();
    $object->initTwoParams($name, $price);
    return $object;
}
  
protected function initTwoParams($price,$name) {
	$this->name = $name;
	$this->price = $price;
}



В таком случае получается:
статичную функцию можно выполнить без создания объекта, и она вернёт нам экземпляр класса product
$product = Products::createWithTwoParams($name,$price);
Но и конструктор мы тоже сможем использовать.
$product = new Prodcuts($id);

Пусть в PHP нет перегрузки и ещё чего то, зато нетсрогая типизация позваляет вытворять то что «взрослым языкам» и не снилось, да и ктому же это очень удобно, а все проблемы с вязанные с недостатком чего-либо можно решить.

PS: мой первый пост, не судите строго.
Tags:
Hubs:
Total votes 8: ↑4 and ↓40
Comments15

Articles