Разделы
Теги | RSS © 2008 – 2017
Контакты
email: igor@veselov.sumy.ua
skype: utz0r2
» » » Страница 4

7. Коротко ООП PHP - Автозагрузка (autoload). Что такое PSR


PSR (Proposing a Standards Recommendation - Предлагаемые рекомендации стандартов). Группа разработчиков путем голосования создают стандарты для php.
Данные стандарты абсолютно независимы друг от друга и разработчик сам может выбирать следовать им или нет.
http://www.php-fig.org/psr/ здесь список на мемент написания статьи, PSR-0 устаревший, с 1,2,3,4,6,7 стандарты приняты, и 5,8,9,10,11 в черновиках еще.
PSR-0: устаревший смотреть PSR-4.
PSR-1: Основные стандарты кодирования
Секция описывает общие правила оформления кода:
- Использование только тэгов <?php и <?=
- Только UTF-8 без BOM для пхп кода
- Не стоит мешать разный функционал в одном файле
- NS и классы должны следовать psr-0
- классы объявляются в `StudlyCase`
- методы объявляются в lower `camelCase`
- константы объявляются в ТАКОМ_ВИДЕ
PSR-2: Стандарты оформления кода
Собственно представляет собой требования к оформлению кода:
- код должен пользовать 4 пробела вместо ТАБ для отделения кода
- длина строки не более 80 символов, ну 120 в крайнем случае
- пустая строка после объявления NS и USE блока
- открывающая скобка `{` объявления класса и методов должна находится на следующей строке, а закрывающая `}` на следующей строке после кода
- для всех свойств и методов обязательно указывать видимость;
ключевые слова `abstract` и `final` указываются до объявления видимости, а `static` после
- После управляющих ключевых слов (команд языка) должен ставиться пробел, не ставится после вызова методов и функций
- Открывающие скобки `{` для команд ставятся на одной строке с ключевым словом, а закрывающая `}` на следующей строке после кода
- Скобки команд `()` не должны начинаться и заканчиваться пробелами
Остальные стандарты можете посмотреть на http://www.php-fig.org/psr/
Пример автозагрузчиков на основе PSR-4 https://github.com/php-fig/fig-standards/blob/master/accepted/ru/PSR-4-autoloader-examples.md

6. Коротко ООП PHP - Исключения (throw catch exception)


Исключения это условия вызывающееся обычно когда ошибка. Они показывают на то, что в процессе выполнения скрипта пошло что-то не так, при этом выполнение скрипта не обязательно останавливается.
<?php

// функция 1 делим на число
function inverse($x) {
	// делить на ноль нельзя
    if ( !$x ) {
        throw new Exception('Деление на ноль.');
    }
    return 1/$x;
}

try {
    echo inverse(5) . "\n";
    echo inverse(0) . "\n";
} catch (Exception $e) {
    echo 'Выброшено исключение: ',  $e->getMessage(), "\n";
}

// Продолжение выполнения
echo "Hello World\n";
В php 7 появился новый класс Throwable, который является родительским интерфейсом для всех объектов, выбрасывающихся с помощью выражения throw, включая классы Error и Exception.

5. Коротко ООП PHP - Абстрактные классы (abstract) и интерфейсы объектов (interface), их отличие


Методы, объявленные абстрактными, несут, по существу, лишь описательный смысл и не могут включать реализации. При наследовании от абстрактного класса, все методы, помеченные абстрактными в родительском классе, должны быть определены в классе-потомке; кроме того, область видимости этих методов должна совпадать (или быть менее строгой).
Интерфейсы объектов позволяют создавать код, который указывает, какие методы должен реализовать класс, без необходимости описывания их функционала. Тела методов интерфейсов должны быть пустыми.
Интерфейс - это абстрактный класс, у которого все методы не реализованы, все публичные и нет переменных класса.
Абстрактный класс - это как ЗАГОТОВКА.
Интерфейс - это как КОНТРАКТ, что обязан выполнять класс.
А теперь в чем же отличие:
- Интерфейсы, в отличии от абстрактных классов, поддерживают множественное наследование. Т.е. класс-потомок может реализовывать 2 или более интерфейсов одновременно: class A implements Int1, Int2, но class A extends AbstrB
- Интерфейс содержит исключительно объявления методов, но не содержит реализации.
- Интерфейс не может включать в себя свойства
- Класс-потомок обязан реализовывать все методы интерфейса
- В интерфейсе все методы открытые
abstract
<?php

abstract class Car {
	public $x;
	public $y;

    public function __construct($x, $y) {
      $this->x = $x;
      $this->y = $y;
    }
	
	abstract public function move ($x, $y);

}

class BMW extends Car {
	
    public function move($x, $y) {
		echo "Движение BMW из координат ($this->x, $this->y) в координаты ($x, $y)<br />";
		$this->x = $x;
		$this->y = $y;
    }
	
}

$auto = new BMW(10, 20);
echo $auto->x;
echo "<br />";
echo $auto->y;
echo "<br />";
$auto->move(5, 15);
interface
<?php

interface Parsed {
	public function Parsed($blah);
}

interface DotSyntax {
	public function UsesDotSyntax();
}

interface Compiled {
	public function isCompiled();
}



class Java implements DotSyntax, Compiled {
	public function __construct() {
		echo 'Java was created<br/>';
		$this->UsesDotSyntax();
		$this->isCompiled();
	}

	public function UsesDotSyntax() {
		echo 'Yes, UsesDotSyntax<br/>';
	}

	public function isCompiled() {
		echo 'Yes, isCompiled<br/>';
	}
}

class PHP implements Parsed {
	public function __construct() {
		echo 'PHP was created<br/>';
		$this->Parsed('Yes, Parsed<br/>');
	}
	public function Parsed($blah) {
		echo $blah;
	}
}

$php = new PHP();
$java = new Java();

4. Коротко ООП PHP - Магические методы (magic methods) __


Магиеские методы - "магия" данных методов сводится к тому, что они могут перехватывать (отсюда их второе название - методы-перехватчики) сообщения, посланные неопределенным (по сути - несуществующим) методам и свойствам
Всегда начинаются с двойного подчеркивания.
__construct() - этот метод запускается автоматически при созданнии экземпляра класса
__destruct() - метод запускается автоматически при уничтожении обьекта
__call(), __callStatic() - перехватывают обращение к несуществующему методу в контексте объекта и в статическом контексте
__get(), __set() - выполняется при чтении/записи данных из недоступных свойств
__isset() - будет выполнен при использовании isset() или empty() на недоступных свойствах
__unset() - будет выполнен при вызове unset() на недоступном свойстве
__sleep() - вызывается, когда объект подвергается сериализации при помощи функции serialize()
__wakeup() - вызывается при восстановлении объекта при помощи функции unserialize()
__toString() - метод, с помощью которого можно обращаться к классу как к строке
__invoke() - вызывается при попытке использовать объект в качестве функции
__set_state() - метод, который вызывается для классов, экспортирующих значения свойств функцией var_export()
__clone() - вызывается при клонировании объекта
__debugInfo() - метод вызывается функцией var_dump(), когда необходимо вывести список свойств объекта
<?php
class Car {

	function __construct() {
		echo 'Конструктор, вызывается автоматически во время создания экземпляра класса <br/>';
	}

	function __destruct() {
		echo 'Деструктор, вызывается автоматически во время уничтожения экземпляра класса <br/>';
	}

    function __call($name, $arguments) {
        // значение $name регистрозависимо
        echo "Вызов метода '$name' " . implode(', ', $arguments). "<br/>";
    }

    static function __callStatic($name, $arguments) {
        echo "Вызов статического метода '$name' " . implode(', ', $arguments). "<br/>";
    }

	function __get($param) {
		echo "Выполнить из за чтения данных из недоступных свойств: $param <br/>";
	}
	
	function __set($name, $value) {
		echo "Выполнить метод из за записи данных в недоступные свойства: $name -> $value <br/>";
		return $this->{$name} = $value; 
	}

    function __isset($name) {
        echo "Установлено ли '$name'? <br/>";
        // return isset($this->data[$name]);
    }

    function __unset($name) {
        echo "Уничтожение '$name' <br/>";
        // unset($this->data[$name]);
    }
	
	function __sleep() {
		echo "Объект подвергается сериализации при помощи функции serialize <br/>";
    }	
	
	// function __wakeup() {
		// echo "Объект подвергается восстановлении при помощи функции unserialize <br/>";
    // }	
	
	function __toString() {
		return "Мы вызвали " . __METHOD__ . "<br/>";
	}
	
	function __invoke($vars) {
		return "Нельзя вызывать класс как функцию <br/>";
	}
	
	function __set_state($an_array) {
		return print_r($an_array) . "<br/>";
	}

	function __clone()	{
		echo 'Вызывается при клонировании объекта <br/>';
	}

	function __debugInfo() {
		echo 'Вызывается при var_dump <br/>';
	}
	
}

$car = new Car();	// __construct
$car->runTest('в контексте объекта');	// __call
car::runTest('в статическом контексте объекта'); // __callStatic
$car->asdfasdf;	// __get
$car->asdfasdf = 'test';	// __set
isset($car->a); // __isset
isset($car->b); // __unset
$a = serialize($car); // __sleep
// unserialize($a); // __wakeup
echo $car; // __toString
echo $car('Пиу'); // __invoke
eval('$b = ' . var_export($car, true) . ';'); 
var_dump($b); // __set_state
$car2 = clone $car; // __clone
var_dump($car2); // __debugInfo

3. Коротко ООП PHP - Обьявление как статические (static) и финальные (final).


Объявление свойств и методов класса статическими позволяет обращаться к ним без создания экземпляра класса.
Финальные классы используются для запрета унаследования, а методы для запрета переопределения.
<?php
class Car {
	
	// доступ к статическим свойствам класса не может быть получен через оператор ->
	public static $name = 'БМВ';
	
	public static function run() {
		
		// псевдо-переменная $this не доступна внутри статического метода
		echo self::$name . ' Едь!';
		
	}
	
}

// final - класс CarAlien не может быть унаследован
final class CarAlien extends Car {
	
	// final - метод Hi не может быть переопределен
    final public static function run() {
		
		// псевдо-переменная $this не доступна внутри статического метода
		echo 'Мы приехали с миром '  .parent::$name . '!';
		
    }
	
}

echo Car::$name;

echo "<br/>";

Car::run();

echo "<br/>";

CarAlien::run();
Использовать статические функции класса можно, не создавая самого экземпляра класса - это экономит память.

2. Коротко ООП PHP - Принципы: инкапсуляция, полиморфизм, наследование


Обьект Car в жизни это слишком обобщенно. Поэтому создадим машины унаследовав родитель-класс Car (наследование), имзеним их свойства и методы при необходимости (полиморфизм), и ограничим области видимости свойств и методов с помощью спецификаторов доступа private, protected, public ( инкапсуляция(сокрытие внутренних процессов)).
<?php
class Car {

	const DOORS = 5;
	const TYPE = 'хетчбек';

	// инкапсуляция	(ограничили область видимости свойств odo только классом Car и его наследникми)
	protected $odo;
	
	public $fuel = 100;
	public $speed = 0;

	public function run( $speed = 0, $time = 0 ) {
		$this->speed = $speed;
		$this->odo = $speed*$time;
		return 'Движемся со скоростью: ' . $speed . ' км/ч. В течении '  .$time . ' часов <br/>';
	}

	public function stop() {
		$this->speed = 0;
		return 'Остановились, наша скорость: 0 км/ч <br/>' . $this->getOdo();
	}

	// инкапсуляция (ограничили область видимости метода getOdo только классом Car)
	private function getOdo () {
		return 'Проехали дистанцию: ' . $this->odo . ' км <br/>';
	}
	
}

// наследование (наследуем класс родитель Car)
class Zaz extends Car {
	
	// полиморфизм (переопределили константы DOORS и TYPE для Zaz)
	const DOORS = 4;
	const TYPE = 'седан';
	
	// полиморфизм (переопределили свойство $fuel)
	public $fuel = 40;

	// расширили новым методом zagloh только для класса Zaz 
	public function zagloh () {
		return 'Заглох... <br/>';
	}
	
}

// наследование (наследуем класс родитель Car)
class Amfibia extends Car {

	// полиморфизм (переопределили метод run, все остальное осталось от класса Car)
	public function run ( $speed = 0, $time = 0, $water = 0 ) {
		$this->speed = $water == 1? $speed/3 :	$speed;
		$this->odo = $this->speed*$time;
		return 'Движемся со скоростью: ' . $this->speed . ' км/ч. В течении '  .$time . ' часов <br/>';
	}
	
	// рашсирили родительский метод stop
	public function stop() {
		return 'Пшшшш... ' . parent::stop();
	}
	
}


// Cоздаем экземпляр объекта класса Zaz
$car = new Zaz();
echo 'У машины: ' . $car::DOORS . ' двери<br/>';
echo 'Тип машины: ' . $car::TYPE . '<br/>';
echo 'В баке: ' . $car->fuel . ' л топлива<br/>';
echo 'Текущая скорость машины: ' . $car->speed . ' км/ч<br/>';
echo $car->run();
echo $car->zagloh();
echo $car->run(60, 10);
echo $car->stop();

// Cоздаем экземпляр объекта класса Amfibia
$car2 = new Amfibia();
echo 'По воде: ' . $car2->run(60, 10, 1);
echo $car2->stop();
«»
Вверх