"Фаина Георгиевна, как ваши дела? - Вы знаете, милочка, что такое говно? Так оно по сравнению с моей жизнью - повидло." Фаина Георгиевна Раневская

Содержание:

Класс (class)

Класс - является одним из базовых понятий объектно-ориентированного программирования.
Классы образуют синтаксическую базу ООП. Их можно рассматривать как своего рода "контейнеры" для логически связанных данных и функций.
Класс - это своеобразный тип данных.
Каждое определение класса начинается с ключевого слова class, затем следует имя класса, и далее пара фигурных скобок, которые заключают в себе определение свойств и методов этого класса.
Класс может содержать собственные константы, переменные (называемые свойствами) и функции (называемые методами).
Пример простого определения класса:

<?php
class SimpleClass
{

// объявление свойства
public $var = 'значение по умолчанию';
// объявление метода
public function displayVar() {
echo $this->var;
}
}
?>

Свойства

Переменные, которые являются членами класса, называются "свойства".
Каждому объявлению свойства, содержащегося в классе, должно предшествовать ключевое слово var.
Область видимости свойства, метода или константы (начиная c PHP 7.1.0) может быть определена путём использования следующих ключевых слов в объявлении: public, protected или private.
Доступ к свойствам и методам класса, объявленным как public (общедоступный), разрешён отовсюду. Модификатор protected (защищённый) разрешает доступ самому классу, наследующим его классам и родительским классам. Модификатор private (закрытый) ограничивает область видимости так, что только класс, где объявлен сам элемент, имеет к нему доступ. Извне её вызов запрещён, как будто её и нет вовсе.
Если объявляется свойство с помощью var вместо public, protected или private, тогда PHP 5 будет рассматривать свойство так, как если оно было объявлено как public.

Объекты (Object)

Объект является одним из базовых понятий объектно-ориентированного программирования.
Объект представляет собой переменную, экземпляр которой создаётся по специальному шаблону, называемому классом.
Если класс можно рассматривать как тип данных, то объект — как переменную (по аналогии). Скрипт может одновременно работать с несколькими объектами одного класса, как с несколькими переменными.
Объект - это совокупность данных (свойств) и функций (методов) для их обработки. Вообще, объектом является все то, что поддерживает инкапсуляцию.
(Инкапсуляция, англ. encapsulation, от лат. in capsula — в информатике размещение в одном компоненте данных и методов, которые с ними работают. Также может означать скрытие внутренней реализации от других компонентов. Например, доступ к скрытой переменной может предоставляться не напрямую, а с помощью методов для чтения (геттер) и изменения (сеттер) её значения.)

<?php
class foo
{
function do_foo()
{
echo "Doing foo.";
}
}
$bar = new foo;

// Теперь $bar хранит все данные класса foo.
$bar->do_foo();
?>

Директива new

Для создания экземпляра класса используется директива new. Новый объект всегда будет создан, за исключением случаев, когда он содержит конструктор, в котором определён вызов исключения в случае ошибки. Рекомендуется определять классы до создания их экземпляров (в некоторых случаях это обязательно).
Если с директивой new используется строка (string), содержащая имя класса, то будет создан новый экземпляр этого класса. Если имя находится в пространстве имён, то оно должно быть задано полностью.
Пример создание экземпляра класса:

<?php
$instance = new SimpleClass();

// Это же можно сделать с помощью переменной:
$className = 'SimpleClass';
$instance = new $className(); // new SimpleClass()
?>


В контексте класса можно создать новый объект через new self и new parent.
Когда происходит присвоение уже существующего экземпляра класса новой переменной, то эта переменная будет указывать на этот же экземпляр класса. То же самое происходит и при передаче экземпляра класса в функцию. Копию уже созданного объекта можно создать через её клонирование.
Пример присваивание объекта:

<?php
$instance = new SimpleClass();
$assigned = $instance;
$reference =& $instance;
$instance->var = '$assigned будет иметь это значение';
$instance = null;
// $instance и $reference становятся null
var_dump($instance);
var_dump($reference);
var_dump($assigned);
?>


Результат выполнения данного примера:
NULL
NULL
object(SimpleClass)#1 (1) {
["var"]=>
string(30) "$assigned будет иметь это значение"
}

В PHP 5.3.0 введены несколько новых методов создания экземпляров объекта.
Пример создание новых объектов:

<?php
class Test
{
static public function getNew()
{
return new static;
}
}
class Child extends Test
{}
$obj1 = new Test();
$obj2 = new $obj1;
var_dump($obj1 !== $obj2);
$obj3 = Test::getNew();
var_dump($obj3 instanceof Test);
$obj4 = Child::getNew(); var_dump($obj4 instanceof Child);
?>


Результат выполнения данного примера:
bool(true)
bool(true)
bool(true)

В PHP 5.4.0 введена возможность обратиться к свойству или методу только что созданного объекта в одном выражении.
Пример доступ к свойствам/методам только что созданного объекта:

<?php
echo (new DateTime())->format('Y');
?>


Результатом выполнения данного примера будет что-то подобное: 2020

Доступ к классам и объектам

В пределах методов класса доступ к нестатическим свойствам может быть получен с помощью объектного оператора ->.
Пример:

<?php
// Создаем новый класс Coor:
class Coor {
// данные (свойства):
var $name;
// Чтобы получить доступ к членам класса внутри класса, необходимо использовать указатель $this, который всегда относится к текущему объекту. $this является ссылкой на вызываемый объект.
// методы:
function Getname() {
echo $this->name;
}
function Setname($name) {
$this->name = $name;
}
}

// Создаем объект класса Coor:
$object = new Coor;
// Теперь для изменения имени используем метод Setname():
$object->Setname("Nick");
// А для доступа, как и прежде, Getname():
$object->Getname();
// Сценарий выводит 'Nick'
?>

Указатель $this можно также использовать для доступа к методам, а не только для доступа к данным:

function Setname($name) {
$this->name = $name;
$this->Getname();
}


Доступ к статическим свойствам осуществляется с помощью :: (двойного двоеточия).
Статические методы - это функции, используемые в контексте класса. Они сами не могут получать доступ ни к каким обычным свойствам класса, потому что такие свойства принадлежат объектам.
Начиная с PHP 5.3.0, существует возможность ссылаться на класс используя переменную. Значение переменной в таком случае не может быть ключевым словом (например, self, parent и static).

Инициализация объектов

Инициализация объекта - присвоить его свойствам первоначальные значения.
Предположим, имя класса Coor и он содержит два свойства: имя человека и город его проживания. Можно написать метод (функцию), который будет выполнять инициализацию объекта, например Init():

<?php
// Создаем новый класс Coor:
class Coor {
// данные (свойства):
var $name;
var $city;

// Инициализирующий метод:
function Init($name) {
$this->name = $name;
$this->city = "London";
}
}

// Создаём объект класса Coor:
$object = new Coor;
// Для инициализации объекта сразу вызываем метод:
$object->Init();
?>


Вызываем функцию сразу после создания объекта, либо вызываем какой-нибудь метод между созданием (оператор new) объекта и его инициализацией (вызовом Init).
Для того, чтобы PHP знал, что определённый метод нужно вызывать автоматически при создании объекта, ему нужно дать имя такое же, как и у класса (Coor):

function Coor ($name)
$this->name = $name;
$this->city = "London";
}

Преобразование в объект

Если object преобразуется в object, объект не изменится.
Если значение другого типа преобразуется в object, создаётся новый экземпляр встроенного класса stdClass. Если значение было NULL, новый экземпляр будет пустым. Массивы преобразуются в object с именами полей, названными согласно ключам массива и соответствующими им значениям:

<?php
$obj = (object) array('1' => 'foo');
var_dump(isset($obj->{'1'}));
// выводит 'bool(false)'
var_dump(key($obj)); // выводит 'int(1)'
$obj = (object) array('1' => 'foo');
var_dump(isset($obj->{'1'}));
// выводит 'bool(true)', начиная с PHP 7.2.0; 'bool(false)' ранее
var_dump(key($obj)); // выводит 'string(1) "1"', начиная с PHP 7.2.0; 'int(1)' ранее
?>

При преобразовании любого другого значения, оно будет помещено в поле с именем scalar соответствующему типу:

<?php
$obj = (object) 'привет';

echo $obj->scalar; // выведет 'привет'
?>

Наследование

Часто необходимо создание классов содержащих переменные и функция аналогичные переменным и функциям из другого уже существующего класса.
Для облегчения этого, классы могут быть расширениями (производными) других классов.
Производный класс имеет все переменные и функции базового класса (это называется "наследование") и, кроме того, все что добавляется в расширенном определении.
Производный класс всегда зависит от одного базового класса, то есть множественное наследование не поддерживается. Классы расширяются при помощи ключевого слова 'extends'.
Если не используется автозагрузка, классы должны быть объявлены до того, как они будут использоваться. Если класс расширяет другой, то родительский класс должен быть объявлен до наследующего класса.
Пример наследования:

<?php
class Foo
{
public function printItem($string)
{
echo 'Foo: ' . $string . PHP_EOL;
}
public function printPHP()
{
echo 'PHP просто супер.' . PHP_EOL;
}
}
class Bar extends Foo
{
public function printItem($string)
{
echo 'Bar: ' . $string . PHP_EOL;
}
}
$foo = new Foo();
$bar = new Bar();

$foo->printItem('baz'); // Выведет: 'Foo: baz'
$foo->printPHP(); // Выведет: 'PHP просто супер'
$bar->printItem('baz'); // Выведет: 'Bar: baz'
$bar->printPHP(); // Выведет: 'PHP просто супер'
?>

Конструктор

Конструктор выглядит как обычный метод PHP, разница заключается только в том, что он начинается с __ двух символов подчёркивания:

__construct ([ mixed $args [, $... ]] ) : void

PHP 5 позволяет объявлять методы-конструкторы. Классы, в которых объявлен метод-конструктор, будут вызывать этот метод при каждом создании нового объекта.
PHP-конструктор вызывается только один раз. Нельзя вызвать конструктор явно, он вызывается автоматически при создании объекта.
Чтобы создать экземпляр класса, используется ключевое слово new, и в этот момент вызывается конструктор.
Это может оказаться полезным, например, для инициализации какого-либо состояния объекта перед его использованием.
Конструкторы, определённые в классах-родителях не вызываются автоматически, если дочерний класс определяет собственный конструктор. Чтобы вызвать конструктор, объявленный в родительском классе, требуется вызвать parent::__construct() внутри конструктора дочернего класса. Если в дочернем классе не определён конструктор, то он может быть унаследован от родительского класса как обычный метод (если он не был определён как приватный).
Пример использования унифицированных конструкторов:

<?php
class BaseClass {
function __construct() {
print "Конструктор класса BaseClass\n";
}
}
class SubClass extends BaseClass {
function __construct() {
parent::__construct();
print "Конструктор класса SubClass\n";
}
}
class OtherSubClass extends BaseClass {

// наследует конструктор BaseClass
}
// Конструктор класса BaseClass
$obj = new BaseClass();
// Конструктор класса BaseClass
// Конструктор класса SubClass
$obj = new SubClass();
// Конструктор класса BaseClass
$obj = new OtherSubClass();
?>


Пример, конструкторы в классах, находящихся в пространстве имен:

<?php
namespace Foo;
class Bar {
public function Bar() {

// рассматривается как конструктор в версиях PHP 5.3.0-5.3.2
// и как обычный метод, начиная с версии PHP 5.3.3
}
}
?>

Деструктор

Деструктор — специальный метод объекта, который вызывается при уничтожении этого объекта (например, после завершения программы).
Деструкторы обычно выполняют служебную работу — закрывают файлы, записывают протоколы работы, разрывают соединения, "форматируют винчестер" — в общем, освобождают ресурсы.
Деструктор — это специальный метод класса с именем __destruct(), который будет гарантированно вызван при потере последней ссылки на объект в программе. Так как деструктор запускается самим PHP, он не должен принимать никаких параметров.

Объявление типов

Объявление типов также известно, как подсказки для типов в PHP 5.
Объявления типов позволяют функциям строго задавать тип передаваемых параметров. Передача в функцию значений несоответствующего типа будет приводить к ошибке: в PHP 5 это будет обрабатываемая фатальная ошибка, а в PHP 7 будет выбрасываться исключение TypeError.
Чтобы объявить тип аргумента, необходимо перед его именем добавить имя требуемого типа. Объявление типов может принимать значения NULL, если значение по умолчанию для аргумента является NULL.
В PHP 7 добавлена возможность объявлять тип возвращаемого значения. Аналогично объявлению типов аргументов можно задать тип значения, которое будет возвращаться функцией. Типы, которые можно объявить для возвращаемых значений те же, что и для аргументов функций.
Режим строгой типизации также работает при объявлении типа возвращаемого значения. В обычном режиме слабой типизации возвращаемое из функции значение приводится к корректному типу. При строгой типизации возвращаемое значение должно быть заданного типа, иначе будет выброшено исключение TypeError.
Начиная с PHP 7.1.0 возвращаемые значения могут быть помечены как обнуляемые, путём добавления префикса в виде вопросительного знака (?) к названию типу. Это означает, что функция возвращает либо значение указанного типа, либо значение NULL.
Если переопределяется родительский метод, возвращаемое значение дочернего метода должно быть того же типа, что и родительского. Если в родительском методе не задан тип возвращаемого значения, то в дочернем методе можно указать любой.
Пример обычное объявление типа возвращаемого значения:

<?php
function sum($a, $b): float {
return $a + $b;
}

// Будет возвращаться значение типа float
var_dump(sum(1, 2));
?>


Результат выполнения данного примера:
float(3)
Пример объявление обнуляемого типа (начиная с PHP 7.1.0)

<?php
function get_item(): ?string {
if (isset($_GET['item'])) {
return $_GET['item'];
} else {
return null;
}
}
?>

Ключевое слово static

Ключевое слово static имеет в PHP три различных значения. Значение первое — статическая локальная переменная:
function foo() {
$a = 0;
echo $a;
$a = $a + 1;
}

foo(); // 0
foo(); // 0
foo(); // 0

В PHP переменные локальны. Это значит, что переменная, определённая и получившая значение внутри функции (метода), существует только во время выполнения этой функции (метода). При выходе из метода локальная переменная уничтожается, а при повторном входе — создаётся заново. В коде выше такой локальной переменной является переменная $a — она существует только внутри функции foo() и каждый раз при вызове этой функции создаётся заново. Инкремент переменной в этом коде бессмысленен, поскольку на следующей же строчке кода функция закончит свою работу и значение переменной будет потеряно. Сколько бы раз мы не вызвали функцию foo(), она всегда будет выводить 0.
Всё меняется, если перед присваиванием поставить ключевое слово static:

function foo() {
static $a = 0;
echo $a;
$a = $a + 1;
}

foo(); // 0
foo(); // 1
foo(); // 2

Ключевое слово static, написанное перед присваиванием значения локальной переменной, приводит к следующим эффектам:
присваивание выполняется только один раз, при первом вызове функции;
значение помеченной таким образом переменной сохраняется после окончания работы функции;
при последующих вызовах функции вместо присваивания переменная получает сохранённое ранее значение.
Такое использование слова static называется статическая локальная переменная.
Статической переменной присваивать можно только константы или константные выражения. Вот такой код:

static $a = bar();

приведёт к ошибке парсера (ПО, выделяющее определённые части информации из массива данных) . Начиная с версии 5.6 стало допустимым присвоение не только констант, но и константных выражений (например — «1+2» или "[1, 2, 3]"), то есть таких выражений, которые не зависят от другого кода и могут быть вычислены на этапе компиляции.
Значение второе - методы существуют в единственном экземпляре:

class A {
public function foo() {
static $x = 0;
echo ++$x;
}
}
$a1 = new A;
$a2 = new A;

$a1->foo(); // 1
$a2->foo(); // 2
$a1->foo(); // 3
$a2->foo(); // 4

"Разные объекты — разные методы" наглядно видно на этом примере, что динамические методы в PHP «не размножаются». Даже если будет сто объектов этого класса, метод будет существовать лишь в одном экземпляре, просто при каждом вызове в него будет пробрасываться разный $this.
Наследование класса (и метода) приводит к тому, что всё-таки создаётся новый метод:

class A {
public function foo() {
static $x = 0;
echo ++$x;
}
}
class B extends A {
}
$a1 = new A;
$b1 = new B;

$a1->foo(); // 1
$b1->foo(); // 1
$a1->foo(); // 2
$b1->foo(); // 2

Динамические методы в PHP существуют в контексте классов, а не объектов. И только лишь в рантайме (run-time - время выполнения, означает работу компьютерной программы, то есть время, когда программа запущена и выполняется) происходит подстановка "$this = текущий_объект".
Значение третье — статические свойства и методы классов.
В объектной модели PHP существует возможность задавать свойства и методы не только для объектов — экземпляров класса, но и для класса в целом. Для этого тоже служит ключевое слово static.
static - это ключевое слово означает, что функция или переменная в действительности является членом класса, а не членом объекта этого класса.
Объявление свойств и методов класса статическими позволяет обращаться к ним без создания экземпляра класса. Свойство класса, объявленное как статическое, не может быть доступно посредством экземпляра класса (но статический метод может быть вызван).
Для доступа к таким свойствам и методам используются конструкции с двойным двоеточием («Paamayim Nekudotayim»), такие как ИМЯ_КЛАССА::$имяПеременной и ИМЯ_КЛАССА:: имяМетода():

class A {
public static $x = 'foo';
public static function test() {
return 42;
}
}

echo A::$x; // 'foo'
echo A::test(); // 42

Так как статические методы вызываются без создания экземпляра класса, то псевдопеременная $this недоступна внутри метода, объявленного как статический.
Это проистекает из самого определения статического метода — поскольку он связан с классом, а не объектом, в нём недоступна псевдопеременная $this, указывающая в динамических методах на текущий объект.
В отличие от других языков, PHP не определяет ситуацию «в статическом методе написано $this» на этапе парсинга или компиляции. Подобная ошибка может возникнуть только в рантайме, если попытаться выполнить код с $this внутри статического метода.
Код типа такого:

class A {
public $id = 42;
static public function foo() {
echo $this->id;
}
}


не приведёт ни к каким ошибкам, до тех пор, пока не попытаться использовать метод foo() неподобающим образом:

$a = new A;
$a->foo();


(и сразу получим «Fatal error: Using $this when not in object context»)
static не аксиома!

class A {
static public function foo() {
echo 42;
}
}
$a = new A;
$a->foo();


Статический метод, если он не содержит в коде $this, вполне можно вызывать в динамическом контексте, как метод объекта. Это не является ошибкой в PHP.
Обратное не совсем верно:

class A {
public function foo() {
echo 42;
}
}
A::foo();


Динамический метод, не использующий $this, можно выполнять в статическом контексте,но получим предупреждение «Non-static method A::foo() should not be called statically» уровня E_STRICT. Здесь необходимо решать — или строго следовать стандартам кода, или подавлять предупреждения. Первое, предпочтительнее.
Всё написанное выше относится только к методам. Использование статического свойства через "->" невозможно и ведёт к фатальной ошибке.

Позднее статическое связывание

В версии 5.3 добавлено «позднее статическое связывание» или LSB (Late Static Binding).
Понять суть LSB проще всего на примерах:

class Model {
public static $table = 'table';
public static function getTable() {
return self::$table;
}
}

echo Model::getTable(); // 'table'

Такая языковая возможность называется «ранним статическим связыванием». Почему ранним? Потому что связывание self и конкретного имени класса происходит не в рантайме, а на более ранних этапах — парсинга и компиляции кода. Ну а «статическое» — потому что речь идёт о статических свойствах и методах.
Изменим код:

class Model {
public static $table = 'table';
public static function getTable() {
return self::$table;
}
}
class User extends Model {
public static $table = 'users';
}

echo User::getTable(); // 'table'

self был связан с классом Model тогда, когда о классе User ещё ничего не было известно, поэтому и указывает на Model.
Для решения этой дилеммы был придуман механизм связывания «позднего», на этапе рантайма. Работает он очень просто — достаточно вместо слова «self» написать «static» и связь будет установлена с тем классом, который вызывает данный код, а не с тем, где он написан:

class Model {
public static $table = 'table';
public static function getTable() {
return static::$table; }
}
class User extends Model {
public static $table = 'users';
}

echo User::getTable(); // 'users'

Это и есть «позднее статическое связывание».
Для большего удобства в PHP кроме слова «static» есть еще специальная функция get_called_class(), которая сообщит — в контексте какого класса в данный момент работает код.
Если говорить более точно, позднее статическое связывание сохраняет имя класса указанного в последнем "не перенаправленном вызове". В случае статических вызовов это явно указанный класс (обычно слева от оператора ::); в случае не статических вызовов это класс объекта.
"Перенаправленный вызов" - это статический вызов, начинающийся с self::, parent::, static::, или, если двигаться вверх по иерархии классов, forward_static_call(). Функция get_called_class() может быть использована для получения строки с именем вызванного класса, а static:: представляет её область действия.
Само название "позднее статическое связывание" отражает в себе внутреннюю реализацию этой особенности. "Позднее связывание" отражает тот факт, что обращения через static:: не будут вычисляться по отношению к классу, в котором вызываемый метод определён, а будут вычисляться на основе информации в ходе исполнения. Также эта особенность была названа "статическое связывание" потому, что она может быть использована (но не обязательно) в статических методах.

Ограничения self::

Статические ссылки на текущий класс, такие как self:: или __CLASS__, вычисляются используя класс, к которому эта функция принадлежит, как и в том месте, где она была определена:

Пример использование self::

<?php
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
self::who();
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test();
?>


Результат выполнения данного примера: A
Ключевое слово self в PHP всегда значит «имя класса, где это слово написано». В данном случае self заменяется на класс A, а self::$table — на A::$table.

Использование позднего статического связывания

Позднее статическое связывание пытается устранить ограничение self::, предоставляя ключевое слово, которое ссылается на класс, вызванный непосредственно в ходе выполнения. Попросту говоря, ключевое слово, которое позволит ссылаться на B из test() в предыдущем примере. Было решено не вводить новое ключевое слово, а использовать static, которое уже зарезервировано.
Пример простое использование static::

<?php
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
static::who();
// Здесь действует позднее статическое связывание
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test();
?>


Результат выполнения данного примера: B
В нестатическом контексте вызванным классом будет тот, к которому относится экземпляр объекта. Поскольку $this-> будет пытаться вызывать закрытые методы из той же области действия, использование static:: может дать разные результаты.
Другое отличие в том, что static:: может ссылаться только на статические поля класса.
Пример использование static:: в нестатическом контексте:

<?php
class A {
private function foo() {
echo "success!\n";
}
public function test() {
$this->foo();
static::foo();
}
}
class B extends A {

/* foo() будет скопирован в В, следовательно его область действия по прежнему А, и вызов будет успешным */
}
class C extends A {
private function foo() {

/* исходный метод заменен; область действия нового метода - С */
}
}
$b = new B();
$b->test();
$c = new C();
$c->test();
// потерпит ошибку
?>

Результат выполнения данного примера:
success!
success!
success!
Fatal error: Call to private method C::foo() from context 'A' in /tmp/test.php on line 9

Разрешающая область позднего статического связывания будет фиксирована вычисляющем её статическим вызовом. С другой стороны, статические вызовы с использованием таких директив как parent:: или self:: перенаправляют информацию вызова.
Пример перенаправленные и не перенаправленные вызовы:

<?php
class A {
public static function foo() {
static::who();
}
public static function who() {
echo __CLASS__."\n";
}
}
class B extends A {
public static function test() {
A::foo();
parent::foo();
self::foo();
}
public static function who() {
echo __CLASS__."\n";
}
}
class C extends B {
public static function who() {
echo __CLASS__."\n";
}
}
C::test();
?>


Результат выполнения данного примера:
A
C
C

Пример отличия "self::", "static::" и "parent::"

Создадим класс 'Model' (базовый) и дочерний 'Users'
1) В этом случае "self::" находится в родительском классе, следовательно берет данные из родительского(от туда где он находится).

class Model {
public static $table='table';
public static function getTable() {
return self::$table;
}
}
class User extends Model{
public static $table='users';
}
echo User::getTable();
//выведет 'table'

2) В этом случае "static::" берет данные из вызывающего класса, в нашем случае 'Users'.

class Model {
public static $table='table';
public static function getTable() {
return static::$table;
}
}
class User extends Model{
public static $table='users';
}
echo User::getTable();
//выведет 'users'

3) Здесь "parent::" используется для доступа к методам и свойствам базового (родительского) класса. Здесь мы, в дочернем классе, переопределили метод базового класса( foo() ), но с помощью "parent::" все ещё можем обратиться к родительскому методу.

class Model {
public static $table='table';
public static function foo() {
echo "1_test";
}
}
class User extends Model{
public static function foo() {
echo "2_test";
parent::foo();
}
}
echo User::foo();
//выведет '2_test1_test'

self — класс в котором написано, заменяется на имя текущего класса.
self - вызываем метод именно этого класса.
static — класс в котором выполнилось.
static - вызываем метод текущего класса.
Разница между self и static хорошо видна, например, делается new self() или new static() - в первом случае будет создан объект класса, где упомянут self (т.е. создан родитель), во втором - объект того класса, где вызывается метод (т.е. потомок).
parent - вызываем родительский метод (не обязательно статичный).
Префикс parent:: очень похож на префикс self::, но заставляет PHP обратиться к функциям родительского (базового) класса, а не текущего.
parent заменяется на имя базового класса.

Финальные методы

PHP 5 предоставляет ключевое слово final, разместив которое перед объявлениями методов класса, можно предотвратить их переопределение в производных классах.
Если же сам класс определяется с этим ключевым словом, то он не сможет быть унаследован.

<?php
class Base {
public final function test() {}
}
class Derive extends Base {
public function test() {}
// Ошибка! Нельзя переопределить
}
?>


При запуске этого несложного сценария выдается ошибка Fatal error: Cannot override final method Base::test()
В PHP, можно не только запретить переопределение методов, но и запретить наследование от указанного класса вообще. Для этого ключевое слово final необходимо поставить перед определением класса, например:

final class Base {}

Теперь нельзя создавать классы, производные от Base.

Пространства имён

Пространство имён (namespace) — это имеющий имя фрагмент программы, содержащий в себе: функции, переменные, константы и другие именованные сущности. Пространства имён? - это один из способов инкапсуляции элементов.
Такое абстрактное понятие можно увидеть например, в любой операционной системе, директории служат для группировки связанных файлов и выступают в качестве пространства имён для находящихся в них файлов. В качестве конкретного примера файл foo.txt может находиться сразу в обеих директориях: /home/greg и /home/other, но две копии foo.txt не могут существовать в одной директории. Кроме того, для доступа к foo.txt извне директории /home/greg, необходимо добавить имя директории перед именем файла используя разделитель, чтобы получить /home/greg/foo.txt. Этот же принцип распространяется и на пространства имён в программировании.
Для получения "извне" доступа к идентификатору из некоторого пространства имён служит синтаксис имяПространстваИмён::имяИдентификатора.
Предположим, что есть два пространства имён: main (основная программа) и lib (библиотека стороннего производителя). И там, и там может быть определена функция length().
При этом доступ к одной функции будет выглядеть как lib::length(), а к другой — main::length(). Причём для кода, который сам находится в пространстве имён main, префикс main:: можно не указывать.
В PHP пространства имён используются для решения двух проблем, с которыми сталкиваются авторы библиотек и приложений при создании повторно используемых элементов кода, таких как классы и функции:
Конфликт имён между кодом и внутренними классами/функциями/константами PHP или сторонними.
Возможность создавать псевдонимы (или сокращения) для Ну_Очень_Длинных_Имен, чтобы облегчить первую проблему и улучшить читаемость исходного кода.
Пространства имён PHP предоставляют возможность группировать логически связанные классы, интерфейсы, функции и константы.
Хотя любой корректный PHP-код может находиться внутри пространства имён, только классы (включая абстрактные и трейты), интерфейсы, функции и константы зависят от него.
Пространства имён объявляются с помощью зарезервированного слова namespace.
Файл, содержащий пространство имён, должен содержать его объявление в начале перед любым другим кодом, кроме зарезервированного слова declare.
Кроме того, в отличие от любой другой конструкции PHP, одно и то же пространство имён можно определять в нескольких файлах, что позволяет распределять их содержимое по файловой системе.
Несколько пространств имён также можно описать в одном файле с помощью двух допустимых синтаксических конструкций:

<?php
namespace MyProject;
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
namespace AnotherProject;
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
?>


Используя директиву use, можно получить класс из другого пространства имён.
Возможность ссылаться на внешнее абсолютное имя по псевдониму или импортированию - это важная особенность пространств имён. Это похоже на возможность файловых систем unix создавать символические ссылки на файл или директорию.
Все версии PHP, поддерживающие пространства имён, поддерживают три вида создания псевдонима имени или импорта: создание псевдонима для имени класса, создание псевдонима для имени интерфейса и для имени пространства имён. PHP 5.6+ также поддерживает импорт функций и имён констант.
В PHP создание псевдонима имени выполняется с помощью оператора use.
Пример, показывающий 5 типов импорт/создание псевдонима имени с помощью оператора use:

<?php
namespace foo;
use My\Full\Classname as Another;

// это тоже самое, что и использование My\Full\NSname as NSname
use My\Full\NSname;
// импортирование глобального класса
use ArrayObject;
// импортирование функции (PHP 5.6+)
use function My\Full\functionName;
// псевдоним функции (PHP 5.6+)
use function My\Full\functionName as func;
// импортирование константы (PHP 5.6+)
use const My\Full\CONSTANT;
$obj = new namespace\Another;
// создает экземпляр класса foo\Another
$obj = new Another; // создает объект класса My\Full\Classname
NSname\subns\func(); // вызывает функцию My\Full\NSname\subns\func
$a = new ArrayObject(array(1)); // создает объект класса ArrayObject
// без выражения "use ArrayObject" мы создадим объект класса foo\ArrayObject
func(); // вызывает функцию My\Full\functionName
echo CONSTANT;
// выводит содержимое константы My\Full\CONSTANT
?>

Исключения

Механизм обработки исключений (exceptions) — это технология, позволяющая писать код восстановления после серьёзной ошибки в удобном для программиста виде.
Исключение — это некоторое сообщение об ошибке вида "серьёзная". При своей генерации оно автоматически передаётся в участок программы, который лучше всего "осведомлен", что же следует предпринять в данной конкретной ситуации.
Этот участок называется обработчиком исключения.
Код обработчика исключения помещается в блок инструкции catch (в переводе с английского — "ловить").
Блок try (в переводе с английского — "попытаться") используется для того, что бы указать в программе область перехвата. Любые исключения, сгенерированные внутри неё (и только они), будут переданы соответствующему обработчику.
Инструкция throw используется для генерации исключения. Генерацию также называют возбуждением или даже выбрасыванием (или "вбрасыванием") исключения (от англ. throw — бросать).
Любое исключение представляет собой обычный объект PHP, который создаётся в операторе new.
В блоке catch указано, в какую переменную должен быть записан "пойманный" объект-исключение перед запуском кода обработчика. Также обязательно задаётся тип исключения — имя класса. Обработчик будет вызван только для тех объектов-исключений, которые совместимы с указанным типом (например, для объектов данного типа).
Инструкция throw не просто генерирует объект-исключение и передаёт его обработчику блока catch. Она также немедленно завершает работу текущего try - блока.
Код генерирующий исключение, должен быть окружен блоком try, для того, чтобы можно было перехватить исключение. Каждый блок try должен иметь как минимум один соответствующий ему блок catch или finally.
Генерируемый объект должен принадлежать классу Exception или наследоваться от Exception. Попытка сгенерировать исключение другого класса приведёт к фатальной ошибке PHP.
Можно использовать несколько блоков catch, перехватывающих различные классы исключений. Нормальное выполнение (когда не генерируются исключения в блоках try) будет продолжено за последним блоком catch. Исключения могут быть сгенерированы (или вызваны ещё раз) оператором throw внутри блока catch.
При генерации исключения код, следующий после описываемого выражения, не будет выполнен, а PHP попытается найти первый блок catch, перехватывающий исключение данного класса. Если исключение не будет перехвачено, PHP выдаст фатальную ошибку: "Uncaught Exception ..." (Не перехваченное исключение), если не был определён обработчик ошибок при помощи функции set_exception_handler().
В PHP 7.1 и выше, блок catch может принимать несколько типов исключений с помощью символа (|). Это полезно, когда разные исключения из разных иерархий классов обрабатываются одинаково.
В PHP 5.5 и более поздних версиях блок finally также можно использовать после или вместо блока catch. Код в блоке finally всегда будет выполняться после кода в блоках try и catch, независимо от того, было ли выброшено исключение, перед тем как продолжится нормальное выполнение кода.
Одно важное взаимодействие происходит между блоком finally и оператором return. Если оператор return встречается внутри блоков try или catch, блок finally все равно будет выполнен. Кроме того, оператор return выполняется, когда встречается, но результат будет возвращён после выполнения блока finally. Если блок finally также содержит оператор return, возвращается значение, указанное в блоке finally.
Внутренние функции PHP в основном используют сообщения об ошибках, и только новые объектно-ориентированные расширения используют исключения. Однако, ошибки можно легко преобразовать в исключения с помощью класса ErrorException.
Стандартная библиотека PHP (SPL) предоставляет хороший набор встроенных классов исключений.
Пример выбрасывание исключений:

<?php
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 "Привет, мир\n";
?>


Результат выполнения данного примера:
0.2
Выброшено исключение: Деление на ноль.
Привет, мир
Пример обработка исключений с помощью блока finally:

<?php
function inverse($x) {
if (!$x) {
throw new Exception('Деление на ноль.');
}
return 1/$x;
}
try {
echo inverse(5) . "\n";
} catch (Exception $e) {
echo 'Поймано исключение: ', $e->getMessage(), "\n";
} finally { echo "Первый блок finally.\n"; } try { echo inverse(0) . "\n"; } catch (Exception $e) { echo 'Поймано исключение: ', $e->getMessage(), "\n"; } finally {
echo "Второй блок finally.\n";
}

// Продолжение нормального выполнения
echo "Привет, мир\n";
?>


Результат выполнения данного примера:
0.2
Первый блок finally
Поймано исключение: Деление на ноль.
Второй блок finally
Привет, мир
Пример взаимодействие между блоками finally и return:

<?php
function test() {
try {
throw new Exception('foo');
} catch (Exception $e) {
return 'catch';
} finally {
return 'finally';
}
}
echo test();
?>


Результат выполнения данного примера:
finally
Пример вложенные исключения:

<?php
class MyException extends Exception { }
class Test {
public function testing() {
try {
try {
throw new MyException('foo!');
} catch (MyException $e) {

// повторный выброс исключения
throw $e;
}
} catch (Exception $e) {
var_dump($e->getMessage());
}
}
}
$foo = new Test;
$foo->testing();
?>


Результат выполнения данного примера:
string(4) "foo!"
Пример обработка нескольких исключений в одном блоке catch:

<?php
class MyException extends Exception { }
class MyOtherException extends Exception { }
class Test {
public function testing() {
try {
throw new MyException();
} catch (MyException | MyOtherException $e) {
var_dump(get_class($e));
}
}
}
$foo = new Test;
$foo->testing();
?>


Результат выполнения данного примера:
string(11) "MyException"

Функции PHP для работы с MySQL

Основной функцией для соединения с сервером MySQL является mysql_connect(), которая подключает скрипт к серверу баз данных MySQL и выполяет авторизацию пользователя базой данных. Синтаксис у данной функции такой:
mysql_connect ([string $hostname] [, string $user] [, sting $password]);
Все параметры данной функции являются необязательными, поскольку значения по умолчанию можно прописать в конфигурационном файле php.ini.
Если необходимо указать другие имя MySQL-хоста, пользователя и пароль, всегда можно это сделать. Параметр $hostname может быть указан в виде: хост:порт.
Для закрытия соединения предназначена функция mysql_close(int $connection_id).
Функция mysql_select_db (string $db [, int $id]) выбирает базу данных, с которой будет работать PHP скрипт. Если открыто не более одного соединения, можно не указывать параметр $id.
Попытка установить соединение с MySQL:

if (!mysql_connect($server, $user, $ password)) {
echo "Ошибка подключения к серверу MySQL";
exit;
}


Соединились, теперь выбираем базу данных:

mysql_select_db($db);

Все запросы к текущей базе данных отправляются функцией mysql_query(). Этой функции нужно передать один параметр - текст запроса. Текст запроса может содержать пробельные символы и символы новой строки (\n). Текст должен быть составлен по правилам синтаксиса SQL.
Пример запроса:

$q = mysql_query("SELECT * FROM mytable");

Приведенный запрос должен вернуть содержимое таблицы mytable. Результат запроса присваивается переменной $q.
Результат - это набор данных, который после выполнения запроса нужно обработать определенным образом.
Если запрос, выполненный с помощью функции mysql_query() успешно выполнился, то в результате клиент получит набор записей, который может быть обработан следующими функциями PHP:
mysql_result() - получить необходимый элемент из набора записей;
mysql_fetch_array() - занести запись в массив;
mysql_fetch_row() - занести запись в массив;
mysql_fetch_assoc() - занести запись в ассоциативный массив;
mysql_fetch_object() - занести запись в объект.
Также можно определить количество содержащихся записей и полей в результате запроса. Функция mysql_num_rows() позволяет узнать, сколько записей содержит результат запроса:

$q = mysql_query("SELECT * FROM mytable");
echo "В таблице mytable ".mysql_num_rows($q)." записей";


Запись состоит из полей (колонок). С помощью функции mysql_num_fields() можно узнать, сколько полей содержит каждая запись результата:

$q = mysql_query("SELECT * FROM mytable");
echo "В таблице mytable ".mysql_num_fields($q)." полей ";


Есть возможность узнать значение каждого поля. Это можно сделать с помощью следующей функции:

mysql_result (int $result, int $row, mixed $field);

Параметр функции $row задает номер записи, а параметр $field - имя или порядковый номер поля.
Предположим, SQL-запрос вернул следующий набор данных:

Email Name Last_Name
------------------------------------
ivanov@mail.ru Ivan Ivanov
petrov@mail.ru Petr Petrov


Вывести это в браузер можно следующим образом:

$rows = mysql_num_rows($q);
$fields = mysql_num_fields($q);
echo "<pre>";
for ($c=0; $c<$rows; $c++) {
for ($cc=0; $cc<$fields; $cc++) {
echo mysql_result($q, $c, $cc)."\t";
echo "\n";
}
}
echo "</pre>";


Скрипт вывода содержимого таблицы MySQL в виде HTML:

<?php
$host = "localhost";
$user = "user";
$password = "secret_password";

// Производим попытку подключения к серверу MySQL:
if (!mysql_connect($host, $user, $password))
{
echo "<h2>MySQL Error!</h2>";
exit;
}

// Выбираем базу данных:
mysql_select_db($db);
// Выводим заголовок таблицы:
echo "<table border=\"1\" width=\"100%\" bgcolor=\"#FFFFE1\">";
echo "<tr><td>Email</td><td>Имя</td><td>Месяц</td>";
echo "<td>Число</td><td>Пол</td></tr>";

// SQL-запрос:
$q = mysql_query ("SELECT * FROM mytable");
// Выводим таблицу:
for ($c=0; $c<mysql_num_rows($q); $c++)
{
echo "<tr>";
$f = mysql_fetch_array($q);
echo "<td>$f[email]</td><td>$f[name]</td><td>$f[month]</td>";
echo "<td>$f[day]</td><td>$[s]</td>";
echo "</tr>";
}
echo "</table>";
?>

Хэш-функции

md5(string $str)
Возвращает хэш-код строки $str, основанный на алгоритме корпорации RSA Data Security под названием "MD5 Message-Digest Algorithm".
Хэш-код — это просто строка, практически уникальная для каждой из строк $str. То есть вероятность того, что две разные строки, переданные в $str, дадут нам одинаковый хэш-код, стремится к нулю.
Если длина строки $str может достигать нескольких тысяч символов, то её MD5-код занимает максимум 32 символа.
Для чего нужен хэш-код и, в частности, алгоритм MD5? Например, для проверки паролей на истинность.
К примеру, есть система со многими пользователями, каждый из которых имеет свой пароль. Можно, конечно, хранить все эти пароли в обычном виде, или зашифровать их каким-нибудь способом, но тогда велика вероятность того, что в один прекрасный день этот файл с паролями у вас украдут.
Сделаем так: в файле паролей будем хранить не сами пароли, а их (MD5) хэш-коды. При попытке какого либо пользователя войти в систему вычислим хэш-код только что введённого им пароля и сравним его с тем, который записан в базе данных. Если коды совпадут, значит, все в порядке, а если нет — что ж, извините...
Конечно, при вычислении хэш-кода какая-то часть информации о строке $str безвозвратно теряется. И именно это позволяет не опасаться, что злоумышленник, получивший файл паролей, сможет его когда-нибудь расшифровать. Ведь в нем нет самих паролей, нет даже их каких-то связных частей!
Пример использования алгоритма хеширования MD5:

<?php
$pass_a = "MySecret";
$pass_b = "MySecret";

// Выводим хеш-код строки MySecret ($pass_a) - исходный пароль
echo "<b>Хеш-код исходного пароля '$pass_a':</b><b style=\"color:green\">".md5($pass_a)."</b><br>";
// Выводим хеш-код строки MySecret ($pass_b) - верифицируемый пароль
echo "<b>Хеш-код верифицируемого пароля '$pass_b':</b><b style=\"color:green\">".md5($pass_b)."</b><br>";
// Сравниваем хеш-коды MD5 исходного и верифицируемого пароля
echo "<h3>Проверяем истинность введенного пароля:</h3>";
if (md5($pass_a)===md5($pass_b)) echo "<h3 style=\"color:green\">Пароль верный! (Хеш-коды совпадают)</h3>";
else echo "<h3 style=\"color:red\">Пароль неверный! (Хеш-коды не совпадают)</h3>"

// В данной ситуации выводит: Пароль верный! (Хеш-коды совпадают)
// Попробуйте изменить значение строки $pass_b :)
?>

HTTP Cookies

PHP прозрачно поддерживает HTTP cookies как определено в » RFC 6265.
Cookies - это механизм для хранения данных в удалённом браузере и, таким образом, отслеживание и идентификации вернувшихся пользователей.
Можно установить cookies, используя функцию setcookie().
Cookies являются частью HTTP-заголовка, поэтому функция SetCookie должна вызываться до того, как браузеру будет отправлен какой бы то ни было вывод. Это то же ограничение, что и для функции header(). Данные, хранящиеся в cookie, доступны в соответствующих массивах данных cookie, таких как $_COOKIE и $_REQUEST.
Чтобы присвоить множество значений одной переменной cookie, можно присвоить их как массив:

<?php
setcookie("MyCookie[foo]", 'Testing 1', time()+3600);
setcookie("MyCookie[bar]", 'Testing 2', time()+3600);
?>


Это создаст две разные cookie, хотя в вашем скрипте MyCookie будет теперь одним массивом.
Если необходимо установить именно одну cookie со множеством значений, сначала рассматриваем возможность использования к значениям такие функции, как serialize() или explode().
Обращаем внимание, что cookie заменит предыдущую cookie с тем же именем в браузере, если только путь или домен не отличаются. Так, для приложения корзины покупок вы, возможно, захотите сохранить счётчик:

<?php
if (isset($_COOKIE['count'])) {
$count = $_COOKIE['count'] + 1;
} else {
$count = 1;
}
setcookie('count', $count, time()+3600);
setcookie("Cart[$count]", $item, time()+3600);
?>

Cтраницы отзывов на сайте без базы данных

Все сообщения будут приходить на email. Закрываем доступ нежелательным IP адресам. Отсеиваем спам который содержит http://. Преграждаем отсылку отзывов роботами.
При первом сообщении создастся файл comments.txt. В него будут попадать все отзывы, кроме тех, которые содержат http://. Отзывы можно добавлять, редактировать или удалять.
Перед началом проверяем отправку писем с помощью PHP.
Создаём файл mail.php следующего содержания:

<?php
var_dump(mail("support@thehost.com","Test","test"));
?>


В браузере запускаем созданный файл по ссылке домен/mail.php и если все работает, получаем ответ bool true, а на указанный ящик придет письмо с темой Test и текстом test. Если не работает, получим bool false, а письмо не придёт.
При удачной проверке в файле .htaccess закрываем доступ к информации comments.txt:

<Files "comments.txt">
Deny from all
</Files>


В корне сайта создаём файл comments.php:

<?php
$z = array($_POST['name'], $_POST['city'], $_POST['e_mail'], date("m.d.Y H:i"), $_SERVER['REMOTE_ADDR'], $_POST['content'], $_POST['robot'] );
# переменная $_SERVER - это массив, содержащий информацию, такую как заголовки, пути и местоположения скриптов. Записи в этом массиве создаются веб - сервером. 'REMOTE_ADDR' IP - адрес сервера, на котором выполняется текущий скрипт
if ($z[0]==NULL && $z[1]==NULL && $z[2]==NULL && $z[5]==NULL && $z[6]==NULL) {
echo <<<TOSHA
<center><form method='post'>
<label>Как к Вам обращаться?</label>
<input type='text' name='name' required/>
<label>Где Вы живёте?</label>
<input type='text' name='city' required/><br><br>
<label>Email (не публикуется)</label>
<input type='email' name='email' required/><br><br>
<label>Oставить отзыв:</label>
<textarea name='content' required rows=10 cols=40></textarea>
<p>Я не Робот</p>
<label>Введите это слово: Кукареку</label>
<input type='text' name='robot' required/><br><br>
<input type='submit' value='отправить отзыв' style='cursor:pointer;'/>
</form></center>
TOSHA;
}
if ($z[0] && $z[1] && $z[2] && $z[5] && $z[4] !== '00.000.000.000' && $z[6] == 'Кукареку' ) {
# 00.000.000.000 блокировка ip адреса
mail("umanov@mail.ru", "Отзывы на 'Установка Linux'", $z[0] . "\n" . $z[1] . "\n" . $z[2] . "\n" . $z[4] . "\n" . $z[5] );
if (strpos($z[3], 'http://') === false) {
# strpos возвращает позицию, в которой находится искомая строка
$fp = fopen("comments.txt", "a+"); # 'a+' открывает файл для чтения и записи; помещает указатель в конец файла. Если файл не существует - пробует его создать.
$mytext = "\n" . $z[0] . "\n" . $z[1] . "\n" . $z[2] . "\n" . $z[3] . "\n" . $z[4] . "\n" . $z[5] ."<br>";
fwrite($fp, $mytext);
fclose($fp);
$dl = '<h2 style="color:green;">Ваш отзыв будет опубликован после проверки администратором сайта.</h2><br>';
echo $dl;
return $dl;
Header("Location: ". $_SERVER['PHP_SELF'] );
# Header отправка HTTP - заголовка. 'PHP_SELF' имя файла скрипта, который сейчас выполняется, относительно корня документов
exit;
} else {
$dl = '<h2 style="color:red;">Что то мне не очень нравится Ваш отзыв!</h2>'; }
} else {
$fp = @fopen("comments.txt", "r");
# 'r' открывает файл только для чтения; помещает указатель в начало файла
if ($fp) {
while (!feof($fp)) {
$dl .= fgetss($fp, 8000,"<br>");
# разрешается не удалять тег <br>
} }
fclose($fp); }
?>
<?php echo $dl; ?>


Логический оператор && (and) выполняет условие только в том случае, если все условия истинные true. Если хотя бы одно условие ложно, то всё условие ложно false.
Когда пишется текст и нужно вставить разрыв строки, необходимо использовать правильные символы. Например в качестве символа конца строки, системы Unix используют \n.
Процесс обьединения двух строк называется "конкатенация". Оператор конкатенации в PHP - это точка (.). Оператор присваивания с конкатенацией (.=), присоединяет правый аргумент к левому.
PHP поддерживает один оператор управления ошибками: знак @. В случае, если он предшествует какому-либо выражению в PHP-коде, любые сообщения об ошибках, генерируемые этим выражением, будут проигнорированы.
Функция fgets(), используется для получения данных из файла, за раз считывает одну строку данных возвращая её значение, сдвигая при этом указатель на следующую строку файла и удаляет любые NULL байты, HTML и PHP-теги из прочитанной строки.
Функция feof(), которая означает "файл конец файла", возвращает false, если в файле ещё остались строки с данными, и true, если программа находится в конце данных файла.
Для вывода всего файла эта функция обычно вызывается в теле цикла (например while), который выполняется до тех пор, пока feof() истинно.

Подключение к базе данных MySql

<?php $link = mysqli_connect("localhost", "root", "xxxyyyzzz", "reviews"); # устанавливает новое соединение с сервером MySQL
# "localhost" может быть именем хоста или IP адресом, "root" имя пользователя MySQL, "xxxyyyzzz" пароль пользователя MySQL, "reviews" имя базы данных
// mysqli_select_db($link, "reviews"); # устанавливает базу данных для выполняемых запросов. Эта функция используется только для смены базы данных во время подключения
// добавить данные в таблицу
$query = "INSERT INTO Отзывы VALUES ( 'null','$z[0]', '$z[1]', '$z[2]', '$z[3]', '$z[4]','$z[5]' )";
if ($result = mysqli_query($link, $query)){
# выполняет запрос к базе данных
echo "<center><table border = 1>\n";
// получить названия полей
echo "<tr>\n";
while ($finfo = mysqli_fetch_field($result)) {
# возвращает информацию об одном столбце результирующего набора в виде объекта. Для получения определения всех столбцов, необходимо запустить функцию многократно
echo "<th>$finfo->name</th>\n"; }
echo "</tr>\n\n";

// получить данные строк и сохранить их в ассоциативный массив
while ($row = mysqli_fetch_assoc($result)) { # извлекает результирующий ряд в виде ассоциативного массива
echo "<tr>\n";
// просмотреть каждое поле
foreach ($row as $col => $val) {
echo "<td>$val</td>\n"; }
echo "</tr>\n\n"; }
echo "</table></center>\n"; }
// Проверка подключения базы данных MySql
if (mysqli_connect_errno()) { # возвращает код ошибки последней попытки соединения
echo "Не удалось подключиться: %s\n", mysqli_connect_error();
exit();
} else {
die ('Подключение к базе данных прошло успешно.'); }
# die - эквивалент функции exit
?>

Случайные числа на PHP

Случайные числа на PHP получаются с исполбзованием функции rand.
Функция rand имеет два параметра. Первый должен содержать наименьшее требуемое значение числа, а второй - наибольшее.
Большинство языков просто генерируют случайное число с плавающей точкой, находящееся в диапазоне от нуля до еденицы, а потом приходится переводить его в нужный диапазон.
PHP позволяет создавать числа в заранее заданном диапазоне.

<?php
$roll = rand(1,6);
if ($roll==1){
echo "<h1>The's an ace!!!</h1>";}
else if ($roll==2){
$binValue = "010";}
else if ($roll==3){
$binValue="011";}
else if ($roll==4){
$binValue="100";}
else if ($roll==5){
$binValue="101";}
else {
echo "Thet's not an ase...";};
echo "In binary, that's $binValue";
echo "<br>";
echo "<img src = die$roll.jpg>";
?>


Первое условие сравнивает значение $roll с еденицей.
Если это так, то выполняется соответствующий участок кода "The's an ace!!!"
Если первое условие не выполняется, программа последовательно проходит все пары операторов
if else до тех пор, пока какой-либо условный оператор не вернёт значение "истина". Если ни одно из условий не истинно, будет выполнен код последнего оператора else.
Вообще условие можно представить как выражение, которое может быть либо истинным (true), либо ложным (false).
Бывает, что нет необходимости в последнем операторе else, однако программы не всегда работают так как ожидается, а по тому не лишним бывает написать код для оператора else. Будет лучше, если программа сообщит о том, что чтото произошло, чем если она внезапно закроется в тот момент, когда с ней работают пользователи.
Иногда последнее возможное значение задаётся ключевым словом default. Оно работает точно так же, как оператор else в структуре if с несколькими сравнениями.
После него помещается код, который будет выполнен в том случае, если не отработает ни один из других операторов case.

default: echo "This is an illegal die!";

Создаём программу добавления почты

Результат работы этой программы в том, что одно и то же письмо используется несколько раз, но каждый раз в нём меняются имена и адреса электронной почты, на полученые из файла.
Файл данных для этой программы является обычным файлом. Каждая строка состоит из имени и адреса электронной почты, разделённых символом пробела.

Nikolay umanov@mail.ru
Sergey polkan@gmail.com
Lubov kukareku@gmail.com

<?php
$theDate = file("comments.txt");
foreach ($theDate as $line) {
$line = rtrim($line);
echo "<h2>$line</h2>";
list($name, $email) = preg_split("/\s+/", $line);
sobaka $message = <<<TOSHA
TO: $email
Dear: $name
"In the whole history of the world there is but one thing that money can not buy... to wit - the wag of a dog's tail". Josh Billings
TOSHA;
echo "<pre>$message</pre>";}
?>


preg_split() разбивает строку по регулярному выражению, в данном случае "/\s+/" (\s пробел, + один или больше)
list() позволяет выделить элементы массива в скалярные переменные.
Довольно часто требуется вывести сразу несколько строк HTML кода, и может оказаться утомительным обрамлять каждую строку кавычками (особенно потому, что в HTML они тоже нередко используются). В языке PHP существует специальный механизм цитирования.
Фрагмент <<<TOSHA показывает, что после него идёт текст, занимающий несколько строк и заканчивающийся символом TOSHA;
Можно использовать вместо "TOSHA" любую фразу на своё усмотрение.
Окончание (в данном случае TOSHA) должно занимать отдельную строку и перед ней не должно быть пробелов.
Следующим очевидным этапом будет автоматическая отправка каждого сообщения в виде электронного письма. Для этого PHP представляет функцию mail().
Работа этой функции зависит от настроек сервера и на каждом сервере она может работать по разному.

PHP

Продаются
книги

Оставить отзыв

Установи и
БУДЕШЬ СЧАСТЛИВ!

Спасибо, Господи, что взял деньгами...

Приму в добрые руки!
Bitcoin 3LN3XUH45XvnRWCgYr4ZcB4P51zfPzKXYe
Dogecoin DL1LyCQkKEUrgBBuWBbgvzb2RR5yeW5RQ9
Litecoin ltc1qr5ntqxafw9jcmq5jfgdhrm0uq306mqntntmhwf
Ethereum 0x0A476b0Fa1DF5a97c911AF4271897153800D23Db
Ryo RYoLsdrYL7sTGXUrtvC9BLLTqTq3YfHdLga33GyhBy4sJ9zV7P8N49RKZmZpU563QsbBLC1UobmCTcwp1QnD6pAXStEtyxVerqn
Monero 4B8tc66Y136YHHEGSioVnpSAW7H5qU5W5MSaXH9RX2QSW6Uy6fFba2S7SndPsJqCXaH7Q4mLduGgZ1UXDx1FAgpoK4Rzvow
Scrooge
Dollar
Ruble
Ruble
Gold