Ооп php



Мы рассмотрим такие понятия, как объектно-ориентированное программирование, классы PHP, конструкторы PHP, деструкторы PHP, магические методы PHP и т.д. Это руководство предназначено для начинающих и опытных программистов, которые хотят изучить PHP ООП, начиная с базового уровня.

Одним из самых значительных изменений в PHP 5 является наличие полностью объектной модели, которая позволяет повысить производительность. К одним из важных новых функций, добавленных в PHP 5, относятся окончательные и абстрактные методы, классы, интерфейсы, клонирование и магические методы. Мы рассмотрим в данном руководстве ООП PHP примеры применения каждого из них.

В объектно-ориентированном программировании объект обрабатывается так же, как ссылки или указатели. Это значит, что каждая новая переменная содержит ссылку на объект, а не копию всего объекта.

Самой трудной для понимания концепцией являются основы ООП, так как они отличаются от обычного программирования на PHP. Но как только вы поймете основные принципы, сама модель станет для вас простой и понятной.

Что такое ООП на PHP?


Поскольку термин объектно-ориентированное программирование начинается со слова «объект«, то мы можем сказать, что это особый тип программирования, при котором создаются и используются объекты.

Вот объяснение ООП PHP для чайников. Посмотрите на мир вокруг нас, он полон объектов. Солнце, луна, автомобили, деревья, дома и т.д. и т.п. Все это объекты, они имеют атрибуты и функции. В процессе мышления мы оперируем объектами. Когда мы говорим об автомобиле, вы не думаете о колесах, двигателе, сиденьях, дверях, вы думаете о машине, как о вещи, которой она является. Проще говоря, вы думаете с точки зрения субъекта или объекта. Объектная ориентация — это представление в программировании элементов как объектов.

Автомобиль является объектом. Он имеет атрибуты цвета, размера, веса и функцию перемещения. Любой объект без функционала будет бесполезным. В ООП программист использует объекты; каждый объект имеет некоторые атрибуты и функции. В целом программирование сводится к построению модулей с помощью объектов.

Простое определение объектно-ориентированного программирования:

Объектно-ориентированное программирование — это программирование на основе объектов, содержащих данные (атрибуты) и методы (функционал), которые обрабатывают эти данные. Объекты — это тип данных, определенных программистом, и взаимодействия между различными объектами также определяется программистом.


Другими словами, ООП позволяет программисту группировать аналогичные задачи в классы, класс может содержать данные и функции для доступа к этим данным, связанные друг с другом.

Основы ООП в PHP помогают разработать более простой в обслуживании и управлении код. Чем более чистым и читаемым является код, тем больше шансов многократно использовать его. В результате к системе могут быть применены шаблоны проектирования. В ООП модули создаются и используются в соответствии с требованиями. С помощью объектно-ориентированного программирования на PHP мы можем создавать приложения для сайтов, которые имеют модульную структуру.

Важные термины руководства по ООП на PHP:

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

Класс

В ООП PHP класс — это тип данных, определенный программистом. Класс содержит данные и функции для работы с этими данными. Данные и функции имеют идентификатор доступа privat. Это означает, что они не видимы за пределами класса. Класс представляет собой шаблон или образец, с которого можно сделать столько копий или экземпляров, сколько необходимо.

Объект

Объект также известен как экземпляр. Когда устанавливается экземпляр класса, создается объект. Если класс — это образец, то объект — это конечное изделие, созданное с помощью образца. После того, как класс был определен, из него может быть создано множество объектов.


Переменная-член

Переменные, определенные в классе, называются переменными-членами. На самом деле это данные, содержащиеся в этом классе, они могут быть изменены функциями только этого класса. Обычно переменные-члены видимы только для этого класса и скрыты от других классов.

Функция-член

Функции, определенные в классе, называются функциями-членами. Они также не видны для других классов. Они используются для изменения переменных-членов, для доступа к данным объекта.

Конструктор

Конструктор — это особый тип функции-члена. Когда устанавливается класс, создается объект, эта функция вызывается автоматически и присваивает начальные значения переменным класса.

Деструктор

Это особый тип функции, которая вызывается автоматически, когда объект удаляется.

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

В PHP 5 ООП наследование – это процесс, при котором класс (подкласс) получает все атрибуты и функции другого класса (суперкласса).

Суперкласс

Также известен как базовый или родительский класс — наследуется одним или несколькими подклассами.

Подкласс

Дочерний или производный класс, подкласс наследуется от суперкласса.

Полиморфизм

Это явление в ООП, при котором одна функция может быть использована для различных целей.


Инкапсуляция

Одна из важнейших концепций объектно-ориентированного программирования. Данные и функции, которые работают с этими данными, связываются между собой и не видны другим функциям.

Абстракция

Абстракция означает, что детали реализации функций или классов не видны.

Перезагрузка

Термин ООП, который означает, что функции, имеющие одинаковые имена, но разное количество аргументов, выполняются по-разному.

Классы и объекты:

Класс и объект широко используются в объектно-ориентированном программировании как термины-синонимы, однако по своей сути они сильно отличаются друг от друга. Класс представляет собой шаблон, образец или форму, а объект является продуктом или деталью, отлитой из этого конкретного шаблона или формы.

Возьмем, к примеру, дом. Класс является основой для дома; он имеет размеры, форму, количество дверей, проходов и т.д. Но это только проект, а не сам дом. Когда построен физический дом на основе информации, содержащейся в плане, то он является объектом.

До этого объект был кучей дерева, кирпича, цемента и т.д., из которых в соответствии с информацией из плана был построен дом или объект:

Класс в PHP ООП — это план или шаблон, по которому устанавливается экземпляр класса, создается объект. После того, как был создан класс, мы можем создать столько объектов, сколько захотим. На рисунке, приведенном выше, из одного класса (плана) были созданы пять объектов (домов). Объект всегда будет соответствовать инструкциям, приведенным в классе, используемом для его создания.

Преимущества ООП на PHP:

  1. Улучшение архитектуры и более чистый код

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

  1. Повторное использование

Объектно-ориентированное программирование делает код повторно используемым. Объекты, созданные однажды, могут быть использованы снова и снова. Программы могут быть построены путем объединения рабочих модулей вместо того, чтобы писать все с нуля. Это экономит время и повышает производительность.

  1. Простота в обслуживании и обновлении

Объекты имеют собственные данные и функции, вся их структура компактна и сжата, что позволяет легко вносить в код изменения. С помощью обычного процедурного программирования создается код, в котором очень трудно найти точку для внесения изменений. В ООП PHP мы можем добавить новое свойство, а затем добавлять связанные методы для управления этим свойством.

  1. Инкапсуляция

Инкапсуляция означает, что значения переменных объекта не видны извне, следовательно, реализуется безопасность данных. Но если возникает необходимость, доступ к данным может быть получен с помощью модификаторов доступа. Для создания безопасных программ данные и функции-члены в классе могут быть скрыты от других классов. Когда объект создан, для его использования не нужна информация о его реализации.

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

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

  1. Меньше ошибок

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

Этот PHP ООП учебник является свободным и полным источником, с помощью которого вы сможете изучить все необходимые приемы.

Перевод статьи «PHP OOP Tutorial» был подготовлен дружной командой проекта Сайтостроение от А до Я.

www.internet-technologies.ru

Что такое объекты в жизни


Давайте рассмотрим пример из жизни, а потом перенесем его на PHP. Пусть у нас есть автомобиль. У него есть колеса, цвет, вид кузова, объем двигателя и так далее. Кроме того, водитель может отдавать ему команды: ехать, остановится, повернуть направо, налево и тп.

Можно говорить о том, что существует некоторый класс автомобилей, обладающий общими свойствами (у всех есть колеса и всем им можно отдавать команды).

Конкретный автомобиль, стоящий на улице — это представитель этого класса, или, другими словами, объект этого класса. У всех объектов этого класса есть свойства (количество колес, цвет, вид кузова) и методы (ехать, остановится, повернуть направо, налево).

Если бы мы программировали автомобиль, то можно было бы сделать что-то вроде такого:

Что в этом коде? Первой строчкой мы создаем объект $мояМашина — представителя класса Автомобиль. У нашей машины появляются свойства и методы, характерные для всех автомобилей — и мы можем отдавать ей команды. Можем также менять и свойства:

По сути в реальной жизни мы всегда имеем дело с объектами — представителями определенного класса. Например, стол, за котором мы сидим, — это объект (конкретный представитель класса Стол).

Как оказалось, программировать в терминах объектов и классов достаточно удобно. Давайте посмотрим, как это делается в PHP.

Наши первые классы и объекты


Давайте сделаем класс User, у которого будет два свойства — имя и возраст (на слово public не обращайте внимание — о нем позже):

Пока наш класс ничего не делает, он просто описывает, что будут иметь объекты этого класса (в нашем случае каждый объект будет иметь имя и возраст). По сути, пока мы не наплодим объектов нашего класса — он мертв и ничего не делает. Давайте же сделаем наш первый объект — представитель класса User:

Обратите внимание на то, что классы принято называть большими буквами (User), а объекты этих классов — маленькими ($user). Кроме того, можно писать new User, а можно — new User() — разницы нет.

Давайте теперь поменяем свойства нашего объекта, а потом выведем их на экран. Обращение к свойствам происходит через стрелочку «->» — имяОбъекта->егоСвойство:

Как вы уже поняли — в свойства объекта можно что-то записывать и из свойств можно выводить их содержимое.

Давайте теперь сделаем 2 юзера (объекта) ‘Коля’ и ‘Вася’, заполним их данными и выведем на экран сумму их возрастов:

Методы

Перейдем теперь к методам. Методы — это по сути функции (обычные функции function, к которым вы привыкли), которые может вызывать каждый объект.

При написании кода разница между методами и свойствами в том, что для методов надо писать круглые скобки в конце, а для свойств — не надо. Пример: $user->name — свойство, а $user->getName() — метод, который что-то делает.


Метод — это практически обычная функция, он может принимать параметры так же, как и все функции.

Давайте потренируемся — сделаем бесполезный тренировочный метод ->show(), который будет выводить ‘!!!’:

Пусть теперь наш метод ->show() выводит нечто полезное — имя пользователя. Это имя можно получить в нашем методе — вопрос как. Если снаружи мы легко можем обратиться к имени через $user->name, то внутри класса следует делать так: $this->name.

Переменная $this указывает на объект класса и предназначена для использования внутри класса.

Итак, сделаем так, чтобы метод show возвращал имя юзера:

Итак, с помощью переменной $this мы можем обратиться к свойствам объекта внутри самого кода объекта. Почему мы не можем обратиться к ним, например, так: $user->name? Потому что переменной $user не существует в момент написания кода класса да и сам класс ничего не знает ни про какую переменную $user.

Через $this можно обращаться не только к свойствам объекта, но и к его методам. Давайте сделаем два метода — метод show(), который будет использовать внутри себя метод getName():

Сделаем что-нибудь полезное с методами

Давайте расширим наш класс User — сделаем метод addYearsToAge, который будет добавлять заданное количество лет к возрасту:

Разбираем public и private


Давайте теперь разберем, что делает ключевое слово public, которое мы писали перед всеми свойствами и методами.

Ключевое слово public указывает на то, что данные свойства и методы доступны извне (вне кода класса). В противоположность public есть ключевое слово private, которое указывает на то, что свойства и методы недоступны извне.

Зачем это надо? К примеру, у нас есть класс, реализующий некоторый функционал. Есть набор методов, но часть этих методов является вспомогательными, и лучше, чтобы их нельзя было использовать вне нашего класса — в этом случае мы легко сможем поредактировать эти вспомогательные методы и можем быть уверенными в том, что их снаружи никто не использует и ничего страшного не случится.

Такой подход называется инкапсуляцией — все лишнее не должно быть доступно извне, в этом случае жизнь программиста станет проще.

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

Давайте попробуем — объявим свойства $name и $age приватными и попытаемся обратиться к ним снаружи — мы сразу увидим ошибку PHP:

Геттеры и сеттеры

Очень часто все свойства объекта делают приватными, а для доступа к ним реализуют специальные методы.

Например, у нас есть свойство ->name — сделаем его приватным, а взамен сделаем метод getName(), который будет возвращать содержимое этого свойства во внешний мир, и метод setName(новое имя), который будет менять значение этого свойства.

Аналогично поступим с возрастом и вот, что у нас получится:

Давайте теперь разбираться, зачем это нужно.

Во-первых, таким образом мы можем создавать свойства только для чтения. Например, возраст можно будет только получить через getAge, но нельзя будет поменять без setAge.

Во-вторых, таким образом мы защищаемся от несанкционированных изменений этого свойства — его нельзя будет затереть случайно, а обязательно нужно будет вызвать метод.

Во-третьих, мы можем проверять, к примеру, новые значения возраста — а вдруг кто-то пытается установить некорректный возраст — реализуем проверку возраста в setAge и будем изменять свойство age, только если возраст корректный.

Такие методы, как мы реализовали, называются геттерами и сеттерами.

Рассмотрим private методы

Давайте для сеттера setAge реализуем вспомогательный private метод checkAge, который будет проверять возраст на корректность перед его установкой:

Метод __construct

Существует специальный встроенный метод __construct. Это метод (если мы его написали в коде) будет вызываться при создании объекта. Пример:

В __construct можно также передавать параметры:

Чем может быть полезен этот метод? Давайте, для примера, сделаем объект User, для которого в момент создания объекта будут указываться имя и возраст. Эти значение в дальнейшем нельзя будет поменять, а только прочитать (геттеры сделаем, а сеттеры нет):

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

Представьте, что у вас есть класс User. Он нужен вам для каких-то целей и в общем-то полностью нас устраивает — доработки этому классу в общем-то не нужны.

Вот этот класс:

А теперь представим себе ситуацию, когда нам понадобился еще и класс Worker (работник). Работник очень похож на юзера, имеет те же свойства и методы, но еще и добавляет свои — свойство $salary (зарплата), а также геттеры и сеттеры для этого свойства.

Что же делать в этом случае? Глупо копировать код класса User и вставлять его в Worker — дублирование кода мы не любим.

Лучше всего будет унаследовать класс Worker от класса User — в этом случае у работника будут все свойства и методы родительского класса (кроме private!) и он спокойно сможет добавить к ним свои.

Наследование реализуется с помощью ключевого слова extends, вот так: class Worker extends User.

Вот реализация класса Worker:

Пусть кроме работника нам нужен еще и студент Student — унаследуем его от User:

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

Я уже писал выше, что private свойства и методы не наследуются. Это не мешает работать public геттерам и сеттерам, унаследованным от User, например: $student->setName() работает, но напрямую получить свойство name внутри класса потомка мы не сможем — это приведет к ошибке.

В общем-то такое поведение должно нас устраивать. Но если не устраивает — нужные нам свойства и методы можно объявить как protected — в этом случае они станут доступны в потомках, но по-прежнему не будут доступны извне.

Давайте в классе Student реализуем метод addOneYear — он будет добавлять 1 год к свойству age. Однако, если в классе User свойство age оставить приватным — мы увидим ошибку:

Для исправления ошибки поправим класс User — сделаем его свойства protected, а не private:

Перегрузка и parent::

Пусть у нас есть класс Student, наследующий от класса User метод setAge. Предположим, что этот метод setAge от родителя нам чем-то не подходит и мы хотим написать свою реализацию в классе-потомке. Так можно делать (это называется перегрузка).

Давайте напишем студент свой setAge в классе Student. Наш setAge будет проверять то, что возраст студента меньше 25 лет:

Пусть мы затерли (перегрузили) метод родителя, но хотели бы использовать и его. То есть мы хотим иметь в классе Student свой метод setAge а также метод родителя setAge. В этом случае к методу родителя можно обратиться так: parent::setAge().

Давайте доработаем наш класс Student так, чтобы использовался метод setAge родителя (убираем некоторое дублирование кода таким образом):

На использование классов внутри других классов

Бывает такое, что мы хотели бы использовать методы одного класса внутри другого, но не хотели бы наследовать от этого класса.

Пусть, к примеру, у нас есть класс User, который хочет использовать класс работы с базами данных Db. Создадим внутри User новый объект класса Db, запишем его в любую переменную, например, в $this->db и будем спокойно использовать public методы и свойства класса Db:

Некоторая практика

Давайте напишем реализацию класса Db и класса User. Попробуйте сами разберитесь в этом коде:

Класс User:

Переменные названия свойств и методов

Названия свойств и методов можно хранить в переменной. К примеру, есть переменная $var, в которой лежит строка ‘name’. Тогда обращение $user->$var по сути эквивалентно обращению $user->name.

Иногда такие финты полезны.

code.mu

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

На основе существующих классов можно создавать новые, используя механизм наследования. Механизм наследования — это использование определенного ранее класса в качестве родительского. При этом набор свойств и методов родительского класса можно расширять. Имейте в виду, что производный класс имеет только одного родителя.

Чтобы создать новый класс, наследующий поведение существующего класса, надо использовать ключевое слово extends в его объявлении. Например:

 class классN2 extends классN1  {  .......  } 

Здесь классN1 — родительский класс, классN2 — производный.

Если производный класс не содержит собственного конструктора, то при создании его объекта используется конструктор родительского класса. Если в производном класса существует собственный конструктор, то конструктор родительского класса не вызывается. При необходимости вызвать конструктор родительского класса это надо сделать явно. Например:

 классN1::классN1(); 

Производный класс будет иметь все свойства и методы родительского класса. Но их можно и переопределить в производном классе.

Пример 4

<html> <head>  <title>Переопределение метода родительского класса</title> </head> <body> <?php class классN3 {  public $имя = "Маша";  function Привет()  {  echo "<H1>".$this->имя."! Привет!</H1>";  } } class классN4 extends классN3 {  function Привет()  {  echo "<H1>".$this->имя."! Какая встреча!</H1>";  } } $obj = new классN4(); $obj->Привет(); ?> </body> </html>

Метод Привет переопределен для производного класса. Свойство имя наследуется от родительского.

Начиная с 4-й версии PHP, в объекте производного класса можно вызвать метод родительского класса, который был переопределен.

Пример 5

<html> <head>  <title>Вызов метода родительского класса</title> </head> <body> <?php class классN5 {  public $имя = "Маша";  function Привет()  {  echo "<H1>".$this->имя."! Привет!</H1>";  }  function Пока()  {  echo "<H1>".$this->имя.", пока!</H1>";  }  }  /**  * Class классN6  */ class классN6 extends классN5 {  /**  *  */  function Привет()  {  echo "<H1>".$this->имя."! Какая встреча!</H1>";  классN5::Привет();  } } $obj = new классN6(); $obj->Привет(); $obj->Пока(); ?> </body> </html>

Итак, производный класс может наследовать, переопределять и дополнять свойства и методы другого класса.

В следующем примере создан класс HTMLTable, основанный на классе Table из примера 3. Новый класс формирует данные, сохраненные методом addRow родительского класса, и выводит их в HTML-таблицу. Свойства $cellpadding и $bgcolor дают возможность изменять соответствующие аргументы, при этом переменной $cellpadding присваивается значение по умолчанию, равное 2.

Пример 6

<html> <head>  <title>Классы Table и HTMLTable</title> </head> <body> <?php  class Tables {  public $headers = [];  public $data = [];  function Tables( $headers )  {  $this->headers = $headers;  }  function addRow ( $row )  {  $tmp = [];  foreach ( $this->headers as $header )  {  if ( ! isset( $row[$header] )) $row[$header] = "";  $tmp[] = $row[$header];  }  array_push ( $this->data, $tmp );  }  function output ()  {  echo "<PRE><B>";  foreach ( $this->headers as $header ) echo "$header ";  echo "</B><BR>";  foreach ( $this->data as $y )  {  foreach ( $y as $x ) echo "$x ";  echo "<BR>";  }  echo "</PRE>";  } }  class HTMLTable extends Tables {  public $cellpadding = "2";  public $bgcolor;  function HTMLTable ( $headers, $bg="FFFFFF" )  {  Tables::Tables( $headers );  $this->bgcolor = $bg;  }  function setCellpadding ( $padding )  {  $this->cellpadding = $padding;  }  function output ()  {  echo "<table cellpadding='".$this->cellpadding."'><tr>";  foreach ( $this->headers as $header )  echo "<th bgcolor='".$this->bgcolor."'>".$header;  foreach ( $this->data as $y )  {  echo "<tr>";  foreach ( $y as $x )  echo "<td bgcolor='".$this->bgcolor."'>$x";  }  echo "</table>";  } }  $test = new HTMLTable ( array("a","b","c"), "#00FFFF" ); $test->setCellpadding ( 7 ); $test->addRow(array("a"=>1,"b"=>3,"c"=>2)); $test->addRow(array("b"=>1,"a"=>3)); $test->addRow(array("c"=>1,"b"=>3,"a"=>4)); $test->output(); ?> </body> </html>

Обратите внимание на то, что значение свойства сellpadding меняется с помощью отдельного метода setCellpadding. Конечно, значения свойств можно менять непосредственно, вне объекта:

 $test->сellpadding = 7 ; 

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

Использовать или нет технику объектного программирования? С одной стороны, проект, интенсивно использующий объектную технику, может занимать слишком много ресурсов во время выполнения. С другой стороны, правильно организованный объектный подход значительно сократит время разработки и сделает программу более гибкой.

Удаление объектов

Удалить ранее созданный объект можно следующим образом:

unset($objName);

Ниже приведен пример, в котором объект класса Саг создается, а затем удаляется.

$myCar = new Car; unset($myCar);

После вызова функции unset() объект больше не существует. В РНР имеется специальный метод __destruct(), который автоматически вызывается при удалении объекта. Ниже приведен класс, содержащий этот метод.

class Bridge {  function __destruct()  {  echo "Мост разрушен";  } } $bigBridge = new Bridge; unset($bigBridge);

При создании объекта класса Bridge, а затем его удалении отобразится следующее сообщение:

Мост разрушен

Оно отображается вследствие вызова метода __destruct() при вызове функции unset(). При удалении объекта может потребоваться акрыть некоторые файлы или записать информацию в базу данных.

Копирование (клонирование) объекта

Клонирование объекта:

$a = clone $b;

Конструктор не вызывается при клонировании, вызывается магический метод __clone(){}. Он НЕ принимает аргументов и к нему нельзя обратиться как к методу.

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

Для конвертации объекта в строку, и обратно, используются следующие функции:
serialize() — принимает объект и возвращает строковое представление его класса и свойств;
unserialize() — принимает строку, созданную при помощи serialize(), и возвращает объект.

serialize() и unserialize() работают со всеми типами данных, но они не работают с ресурсами.

Специальные методы для обслуживания функций serialize() и unserialize():
__sleep() — вызывается строго перед тем, как объект сериализуется с помощью функции serialize(). Функция __sleep() должна будет вернуть список полей класса, которые функция serialize() включит в возвращаемую строку. Вы можете использовать это для того, чтобы исключить ненужные поля из строкового представления объекта. Например:

public function __sleep() { // почистить  return array_keys( get_object_vars( $this ) ); }

__wakeup() — вызывается сразу после того, как объект десериализуется с помощью unserialize().

Абстрактный класс

Абстрактный класс — это класс, который не может быть реализован, то есть, вы не сможете создать объект класса, если он абстрактный. Вместо этого вы создаете дочерние классы от него и спокойно создаете объекты от этих дочерних классов. Абстрактные классы представляют собой шаблоны для создания классов.

abstract class Person {   private $firstName = "";  private $lastName = "";   public function setName( $firstName, $lastName ) {  $this->firstName = $firstName;  $this->lastName = $lastName;  }   public function getName() {  return "$this->firstName $this->lastName";  }   abstract public function showWelcomeMessage();  /* абстрактный метод showWelcomeMessage().  Так как он абстрактный, в нем нет ни строчки кода, это просто его объявление.  Любой дочерний класс обязан добавить и описать метод showWelcomeMessage() */ }

Интерфейс

Интерфейс — это шаблон, который задает поведение одного или более классов. Вот основные отличия между интерфейсами и абстрактными классами:

  • Ни один метод не может быть описан в интерфейсе. Они все абстрактны. В абстрактном классе могут быть и не абстрактные методы.
  • Интерфейс не может содержать полей — только методы.
  • Класс имплементирует интерфейс, и класс наследует или расширяет другой класс.
  • Класс может имплементировать несколько интерфейсов одновременно. Этот же класс может наследовать другой класс. Но у дочернего класса может быть только один супер-класс (абстрактный или нет).
interface MyInterface {  public function aMethod();  public function anotherMethod(); }  class MyClass implements MyInterface {   public function aMethod() {  // (имплементация метода)  }   public function anotherMethod() {  // (имплементация метода)  } }

Методы-перехватчики (магические методы)

  • __get($property) — вызывается при обращении к неопределенному свойству
  • __set($property,$value) — вызывается, когда неопределенному свойству присваивается значение
  • __unset($property) — вызывается, когда функция unset() вызывается для неопределенного свойства
  • __isset($property) — вызывается, когда функция isset() вызывается для неопределенного свойства
  • __call($method,$arg array) — вызывается при обращении к неопределенному методу
  • __callStatic($method,$arg array) — вызывается при обращении к неопределенному статическому методу
  • __toString() — Вызывается, если есть попытка вывести объект, как строку.
  • __debugInfo() — В PHP 5.6 был добавлен новый магический метод, который позволяет менять свойства и значения объекта, когда он печатается с помощью функции var_dump(класс).
  • __invoke() — для вызова объекта как функции. Пример

Пример использования необъявленных свойств класса

Где и зачем могут быть использованны методы-перехватчики?

Например есть у вас таблица в базе данных, называется user и есть в ней некие поля, например id, name, email, phone, password, avatar И Вы создали класс на для работы с юзерами, так его и назвали — User

Какие свойства будут у данного класса? Если вы сделаете такие же как в БД — id, name, email и так далее, то получается что при каждом изменении базы данных — вам нужно менять код в классе User, как то не очень удобно. Добавили вы например поле site — значит нужно его добавлять и в класс User, ну и так далее.
Используя же методы __get() и __set() Вы можете это всё автоматизировать. У вас в классе User вообще не будет ни одного свойства из БД, у нас есть допустим только одно $data — мы туда взяли, да и загрузили всё что есть в базе данных на данного пользователя. А потом, когда программист что то запрашивает, например $user->email мы просто в __get() методе можете посмотреть — если мы такую информацию загрузили из БД, и она лежит в $data[’email’] — то вот мы её вам и возвращаем. А в __set() наоборот. Есть такое поле в БД? Значит присвоим ему новое значение.

/**  * Class User  * @property-read integer id текущего пользователя  * @property-write String site возвращает ссылку на сайт пользователя  */ class User {  private $data;  private $f_write=false;  public function __set($name, $value) {  $this->data[$name] = $value;  $this->f_write=true; // признак, что нужно сохранить данные  }   public function __get($name) {  if(empty($data)){  // читаем запись из БД в data  }  return $this->data[$name];  }  function __destruct()  {  if(!empty($data)&&$this->f_write){  // сохраняем изменения в БД  }  } }  $user=new User(); $user->site='http://kdg.htmlweb.ru/'; //присваеваем переменной echo $user->site; //выводим значение переменной // записываем в БД. Можно это явно не делать, т.к. при окончании работы скрипта это поизойдет автоматически unset($user);

Пример использование необъявленного свойства класса как элемент массива

Обратите внимание на то, что из __get возвращается ссылка:

class Foo {  private $data = [];  public function __set($name, $value) {  $this->data[$name] = $value;  }   public function & __get($name) {  return $this->data[$name];  } }  $foo = new Foo(); $foo->bar[2] = 'lol'; var_dump($foo->bar);

Использоватние перехватчиков обращения к необъявленным методам класса

class OurClass {  public function __call($name,array $params)  {  echo 'Вы хотели вызвать $Object->'.$name.', но его не существует,  и сейчас выполняется '.__METHOD__.'()';  return;  }   public static function __callStatic($name,array $params)  {  echo 'Вы хотели вызвать '.__CLASS__.'::'.$name.', но его не существует,  и сейчас выполняется '.__METHOD__.'()';  return;  } }  $Object=new OurClass; $Object->DynamicMethod(); OurClass::StaticMethod();

Пример обхода закрытых метов класса:

class _byCallStatic{  // Пример обхода "закрытых" методов класса,  // при использовании метода "__callStatic()" для вызова статического метода.  public static function __callStatic($_name, $_param) {  return call_user_func_array('static::'. $_name, $_param);  }  private static function _newCall(){ echo 'Method: '. __METHOD__; } } echo _byCallStatic::_newCall(114, 'Integer', 157); # Результат: Method: _byCallStatic::_newCall

Как вызвать через статический метод любой динамический:

/**  * Class o  * @method static void __f(int $a1 = 1)  */ class o {  public static function __callStatic($method, $args)  {  $class = get_called_class();  $obj = new $class($args[0]);  $method = substr($method, 2);  $pass = array_slice($args,1);  $reflection = new ReflectionMethod($obj, $method);  return $reflection->invokeArgs($obj, $pass);  }   public function f($a1 = 1) {  var_dump('oo', func_get_args());  } } class a extends o {  public function f($a1 = 1, $a2 = 2) { var_dump('aa', $a1 ); } } class b extends o {  public function f($b1 = 1) { var_dump('bb', $b1); } } a::__f(1,2,3); b::__f(4,5,6);

Полезное описание работы с ReflectionClass, когда вы можете проанализировать свойства и методы класса, проверить параметры по шаблонам и т.д.: http://habrahabr.ru/post/139649/

Как использовать объект как функцию?

class Dog {  private $name;  public function __construct($dogName = 'Тузик') {  $this->name = $dogName;  }  public static function __invoke() {  $args = func_get_args();  echo 'Собака получила: ' . implode(' и ', $args);  } }  $dog = new Dog('Мухтар'); $dog('кость', 'поводок');

Как обращаться к объекту как к массиву?

Для этого необходимо создать такой объект который реализует интерфейс ArrayAccess из SPL. Следующий пример реализует объект доступ к данным которого можно получать как в стиле обращения к массиву, так и через получение свойств:

class MyArray implements ArrayAccess {  protected $arr = array();  public function offsetSet($key, $value) {  $this->arr[$key] = $value;  }  public function offsetUnset($key) {  unset($this->arr[$key]);  }  public function offsetGet($key) {  return $this->arr[$key];  }  public function offsetExists($key) {  return isset($this->arr[$key]);  }  public function __get($key)  {  return $this->offsetGet($key);  }  public function __set($key, $val)  {  $this->offsetSet($key, $val);  } } $a = new MyArray(); $a['whoam'] = 'Я значение массива, или объекта? <br/ >'; echo $a['whoam']; echo $a->whoam;

Автозагрузка классов

Файлы автозагружаемых классов обычно располагаются в общем месте, например в /include/class/. Имя файла формируется в формате ИМЯ_КЛАССА.php. Данный код необходимо подключить во все PHP-скрипты:

spl_autoload_register(function ($class_name) {  //echo "Autoload ".$class_name;  $file = $_SERVER['DOCUMENT_ROOT'] . "/include/class/" . strtolower($class_name) . '.php';  if (file_exists($file) == false) {  if($GLOBALS['DEBUG']) echo "Нет файла ".$file;  return false;  }  include_once($file);  return true; });

Для автоподгрузки классов можно также использовать определение функции __autoload();

htmlweb.ru

Основная терминология

Для дальнейшего изучения объектно-ориентированного программирования необходимо понять несколько терминов:

  • Класс — шаблон, описывающий, какими данными и поведением будут обладать реальные объекты. Класс не осязаем, и существует как трафарет для создания конкретных объектов.
  • Свойства — именуемые контейнеры для хранения данных. Имена свойств определяются на подобии обычных переменных, но существуют только в контексте класса. Свойство в ООП описывает объект реального мира. Например, класс Horse может иметь свойство $hairColor описывающее цвет шерсти.
  • Методы — функции, существующие в контексте класса. Они предназначены для манипулирования значениями свойств, а также выполнения любой другой логики, необходимой для существования объектов. Например, класс Horse может содержать метод runGallop(), что соответствует бегу галопом.
  • Объект — экземпляр класса, созданный с него как по трафарету, но имеющий собственные значения свойств. Так один объект класса Horse может иметь значение свойства $hairColor равное «Черные», а другой «Белые».

Для наглядности, мы приводим пример кода, демонстрирующий полный цикл по работе с ООП в PHP: определение класса с набором свойств и методов, создание объекта и его использование. В следующих статьях мы подробно разберем все аспекты работы с объектно-ориентированным подходом программирования. Сейчас вы можете просто скопировать код и посмотреть, как это работает.

  //Определение класса "автомобиль"  class Car  {   //Свойство определяет максимальную скорость   public $maxSpeed;     //Метод вывода сообщения о скорости езды   public function driveFast()   {   echo 'Едем '. $this->maxSpeed .'км/ч!';   }  }    //Создаем объект(экземпляр класса) автомобиля и  //назначаем ему свойство максимальной скорости  $myCar = new Car();  $myCar->maxSpeed = 120;    //Вызываем метод созданного объекта автомобиля  $myCar->driveFast(); //Результат: Едем 120км/ч!

coder-booster.ru

Объектно-Ориентированное программирование давно уже шагнуло в жизнь программистов. Оно везде используется. И кодить на процедурке — это уже даже и не модно. Но начинающим программистам очень сложно перейти на новый уровень — перейти от процедурного программирования к ООП. Порою пугают эти не понятные наборы символов, и не понятно от куда что берется. Да еще это странное переименование переменной в свойство, а функции в метод — вообще отбрасывает всякое желание изучать ООП и многие прогеры ломаются на этом и становятся "непрогерами".

Процедурное программирование оно хорошо для мелких задач, но если уже речь идет о большом проекте, то лучше ООП. Тем более что все фреимворки использут ООП в своей архитектуре. А FrameWork это скорость. А если нужна скорость, то без ООП увы никак.

И так. Тут я приведу список основ PHP ООП, которые всегда должны быть под рукой у начинающего PHP ООП прогера. Ибо когда вы начнете читать код, то должны иметь представление о том, что там написанно.

создание объекта:

  $obj = new CassName();  $obj->methodClass(); // это обращение к методу класса  $obj->svoistvoClass; // это обращение к своиству класса

 конструктор и деструктор

  function __construct(){} // это метод, который срабатывается во момент создания объекта  function __destruct(){} // это метод, который срабатывается во момент удаления объекта  //!!!важно!!!  //в конструктор можно передавать переменные  //в деструктор нельзя, так как если передать переменную, которая будет удалена, то это приведет к ошибке

вспомогательные константы

  echo __CLASS__; // выведет название класса  echo __METHOD__; // выведет название объект::метод

 спецификаторы доступа или (инкапсуляция)

  public //- могу получить доступ из кода и из классов(родительский и наследуемый)  protected //- могу получить доступ только из классов(родительский и наследуемый)  private //- могу получить доступ только из родительского класса

 указание на родительский метод

  parent::classMethod();

 перебор свойств объекта

  foreach ($objName as $name=>$value)  {   echo "$name: $value";  }  // $objName можно заменить на $this (если я использую это в классе), чтоб указать, что можно использовать любой объект, а не какой-то конкретно

костанты склассов

  const CONST_NAME = 'данные константы'; // объявление константы в классах  echo USER::CONST_NAME; // вывод константы вне класса, где USER это название класса, а CONST_NAME это название константы  echo self::CONST_NAME; // вывод константы внутри класса, где CONST_NAME это название константы

 проверяем если объект является экземпляром класса

  if ($object_name instanceof ClassName) {}

исключения (они нужны для отлова ошибок)

  try  {   // some code   if ($error) throw new Exceprion("Тут ошибка");  }  catch(Extension $e)  {   echo $e->getMessage();  }

 перегрузка стандартных PHP классов (то есть наследование класса)

  class MyException extends Exception  {   function __construct($msg)   {   parent::__construct($msg);   }  }

 МЕЛКИЕ ВАЖНЫЕ ПОЛЕЗНЫЕ ФИШКИ

абстрактные классы и интерфейсы используются для описания наших классов,
то есть здесь мы задаем шаблоны по которым будут работать наши наследуемые классы

абстрактный класс (abstract) — это шаблон, который содержит в себе объявление методов
если в абстрактном классе есть абстрактный метод, то он должен быть перегружен

  abstract class MyClass {}

интерфейсы — это тоже абстрактный класс, но который содержит только абстрактные методы

так же нужно перегружать методы

  interface MyClass{}  class MyNaslednik implements MyClass{}

метод — FINAL — нельзя перегрузить

  final function Mymethod(){}

автоматическая подгрузка склассов

то есть если представить себе ситуацию, что вы используете несколько экземпляров разных классов и чтоб избавиться от бесконечных include (require), лучше один раз указать !!!ФУНКЦИЮ!!! __autoload

  // это функция, а не метод  function __autoload($className)  {   include($className);  }

 магический методы __set() и _get()

__set() — срабатывает автоматически в том случае, когда мы присваиваем какое-то значение не известному(не объявленному) свойству

  function __set($objName, $objValue)  {   $this->someVar[$objName] = $objValue;  }

 __get() — срабатывает автоматически в том случае, когда мы пытаемся получить значение не известного(не объявленного) свойства

  function __get($objName)  {   return $this->someVar[$objName];  }

магический метод __call() срабатывает автоматически в том случае, когда мы пытаемся вызвать не известный(не объявленный) метод

  function __call($methodName, $params){}

магический метод __toString() срабатывает автоматически в том случае, когда мы пытаемся вывести объект

  $obj = name Class();  echo $obj;  function __toString()  {   // что-то сделать...  }

zawebis.com

Любую задачу (решаемую в принципе) можно реализовать как с ООП, так и без него (в процедурном стиле, например). «Прелести» ООП лучше всего чувствуются на больших проектах, где невозможно держать в голове все (глобальные) переменные и функции и способы их взаимодействия и приходишь к пониманию необходимости использовать более высокие уровни абстракции, чем отдельные значения и классические массивы из них. Начинаешь объединять семантически связанные данные в структуры (ассоциативные массивы в PHP), а функциям с ними работающим давать имена с префиксом (обычно) в виде названия (чисто семантическое) этих структур, чтобы хоть немного упорядочить глобальное пространство имён, получая функции вида user_login(array $user, $login, $password), user_logout(array $user) и user_is_logged(array $user). До простейшего ООП осталось сделать один шаг — перенести и функции (указатели на них в С, callback/имена в PHP) в эти структуры, но синтаксис вида call_user_func($user['user_login'], $user, $login, $password) мягко говоря неудобен и избыточен и тут в PHP4 вводят вместо него синтаксис $user->login($login, $password) и без него ты больше не можешь жить 🙂

Если же до семантических концепций ООП не дойти на своей шкуре, то разницы между user_login(array $user, $login, $password) и $user->login($login, $password) почти нет, но даже на таком простом примере видно, что запись банально короче и глобальное пространство имён меньше используется, что особенно заметно при использовании IDE с автодополнением.

Но это философское отступление было о некоторых прелестях ООП. Прямой ответ на вопрос «какую задачу?» — любую интересную хотя бы чуть-чуть. Желательно с развитой предметной областью, в которой ощущается интуитивно наличие нескольких абстракций разного уровня. Если для процедурного приложения вы создаёте несколько таблиц в БД или используете ассоциативные массивы для группировки семантически близких значений — то это, скорее всего, такая задача. Для большего wow-эффекта или просветления можно попробовать написать две версии одного приложения типа блога, одну в процедурном стиле, другую в ООП. Причём в первой желательно не использовать «промежуточные» решения типа ассоциативных массивов даже для mysql_fetch_assoc/array(), только бескомпромиссное mysql_fetch_row(). Если же без ассоциативных массивов вы уже разработки не представляете, то вы уже почти достигли ОО-просветления 🙂

toster.ru

Функция connect()

Эта функция будет довольно простой, но прежде чем писать функцию, нам потребуется определить несколько переменных. Переменные должны быть доступны только в пределах класса, поэтому перед каждой переменной стоит ключевое слово private (закрытый). Все переменные (хост, имя пользователя, пароль, имя база данных) используются для соединения с базой данных MySQL. После этого мы сможем создать простой MySQL запрос к базе данных. Конечно, как программисты, мы должны ожидать от пользователей все что угодно, и исходя из этого, нам необходимо принять определенные меры предосторожности. Мы можем проверить: если пользователь уже подключен к базе данных, то , соответственно, ему не нужно повторно подключаться к БД. В противном случае, мы можем использовать учетные данные пользователя для подключения.

PHP

private db_host = ‘’;  private db_user = ‘’;  private db_pass = ‘’;  private db_name = ‘’;     /*   * Соединяемся с бд, разрешено только одно соединение   */    public function connect()   {   if(!$this->con)   {   $myconn = @mysql_connect($this->db_host,$this->db_user,$this->db_pass);   if($myconn)   {   $seldb = @mysql_select_db($this->db_name,$myconn);   if($seldb)   {   $this->con = true;   return true;   } else   {   return false;   }   } else   {   return false;   }   } else   {   return true;   }   }

Как видите выше, мы используем базовые функции MySQL и делаем небольшую проверку на ошибки, чтобы все шло по плану. Если пользователь подключился к БД, мы возвращаем true , в ином случае возвращаем false. В качестве дополнительного бонуса устанавливаем переменную ( con ) в true, если соединение установлено.

Общедоступная ( public ) функция disconnect()

Функция проверяет переменную соединения на существование. Если соединение установлено ( con есть), то закрываем соединение с БД MySQL и возвращаем true . Иначе делать ничего не нужно.

PHP

public function disconnect()  {   if($this->con)   {   if(@mysql_close())   {   $this->con = false;   return true;   }   else   {   return false;   }   }  }

Общедоступная (public) функция select()

Переходим к той части, где все немного усложняется. Мы начинаем работать с аргументами пользователя и возвращаем результаты запроса. У нас нет необходимости использовать результаты прямо сейчас, но нам необходимо создать переменную, в которой мы будем хранить пользовательские результаты по запросам из БД. Кроме того мы также создадим новую функцию, которая будет проверять существует ли данная таблица в БД. Эта функция будет создана отдельно, так как все наши CRUD операции потребуют такой проверки. Таким образом, это немного очистит наш код и в дальнейшем будет способствовать оптимизации кода. Ниже приведена функция для проверки таблиц ( tableExists ) и общедоступная переменная с результатами запросов.

PHP

private $result = array();     /*   * Проверяем наличие таблицы при выполнении запроса   *   */    private function tableExists($table)   {   $tablesInDb = @mysql_query('SHOW TABLES FROM '.$this->db_name.' LIKE "'.$table.'"');   if($tablesInDb)   {   if(mysql_num_rows($tablesInDb)==1)   {   return true;   }   else   {   return false;   }   }   }

Эта функция просто проверяет наличие нужной таблицы в БД. Если таблица существует, вернет true , иначе вернет false .

PHP

   /*   * Выборка информации из бд   * Требуется: table (наименование таблицы)   * Опционально: rows (требуемые колонки, разделитель запятая)   * where (колонка = значение, передаем строкой)   * order (сортировка, передаем строкой)   */     public function select($table, $rows = '*', $where = null, $order = null)   {   $q = 'SELECT '.$rows.' FROM '.$table;   if($where != null)   $q .= ' WHERE '.$where;   if($order != null)   $q .= ' ORDER BY '.$order;   if($this->tableExists($table))   {   $query = @mysql_query($q);   if($query)   {   $this->numResults = mysql_num_rows($query);   for($i = 0; $i < $this->numResults; $i++)   {   $r = mysql_fetch_array($query);   $key = array_keys($r);   for($x = 0; $x < count($key); $x++)   {   // Sanitizes keys so only alphavalues are allowed   if(!is_int($key[$x]))   {   if(mysql_num_rows($query) > 1)   $this->result[$i][$key[$x]] = $r[$key[$x]];   else if(mysql_num_rows($query) < 1)   $this->result = null;   else   $this->result[$key[$x]] = $r[$key[$x]];   }   }   }   return true;   }   else   {   return false;   }   }  else   return false;   }

На первый взгляд выглядит устрашающе, но при этом здесь мы делаем целую кучу важных вещей. Функция принимает четыре аргумента, один из которых обязательный. Функция вернет результат при наличии единственного аргумента — имени таблицы. Однако вы можете расширить количество аргументов и добавить новые аргументы, которые вы сможете использовать при работе с БД; ведь корректное исполнение функции зависит от одного аргумента – имени таблицы. Код в пределах функции служит для компиляции всех аргументов в select запрос. Как только запрос будет составлен, понадобится проверка на наличие в БД нужной таблицы – для этого используется функция tableExists . Если таблица найдена, то функция будет продолжена и запрос будет отправлен. Иначе все застопорится.

В следующей секции приведен действительно магический код. Суть в следующем: собрать данные запрошенные из таблицы. Затем присваиваем наш результат переменной. Чтобы упростить результат для конечного пользователя вместо числовых ключей будем использовать имена столбцов. В случае если количество строк таблицы больше единицы, на выходе вы получите двумерный массив, в котором первый ключ — это число (инкремент), второй ключ — это название колонки. Если в таблице всего одна строка, будет возвращен одномерный массив, название ключей которого соответствует именам столбцов таблицы. Если строк в таблице не найдено, переменной result будет присвоено значение null . Как я сказал ранее, все выглядит немного запутанным, но стоит вам разбить код на отдельные секции все станет гораздо проще и понятнее.

Общедоступная ( public ) функция insert()

Эта функция немного проще, чем предыдущие. Она просто позволяет вставить информацию в БД. Таким образом, помимо имени таблицы нам потребуются дополнительные аргументы. Нам потребуется переменная, которая будет содержать соответствующие для вставки в таблицу значения. Затем мы просто отделим каждое значение запятой. Также мы проверяем при помощи функции tableExists наличие нужной таблицы и составляем insert запрос, манипулируя аргументами, переданными в функцию insert() . Затем отправляем наш запрос по нужному адресу.

PHP

     /*   * Вставляем значения в таблицу   * Требуемые: table (наименование таблицы)   * values (вставляемые значения, передается массив значений, например,   * array(3,"Name 4","this@wasinsert.ed"); )   * Опционально:   * rows (название столбцов, куда вставляем значения, передается строкой,   * например, 'title,meta,date'   *   */     public function insert($table,$values,$rows = null)   {   if($this->tableExists($table))   {   $insert = 'INSERT INTO '.$table;   if($rows != null)   {   $insert .= ' ('.$rows.')';   }   for($i = 0; $i < count($values); $i++)   {   if(is_string($values[$i]))   $values[$i] = '"'.$values[$i].'"';   }   $values = implode(',',$values);   $insert .= ' VALUES ('.$values.')';   $ins = @mysql_query($insert);   if($ins)   {   return true;   }   else   {   return false;   }   }   }

Как видите эта функция довольно простая, по сравнению с составлением запросов select к БД. На самом деле функция delete будет еще проще.

Общедоступная ( public ) функция delete()

Эта функция просто удаляет таблицу или строки из нашей БД. Таким образом, нам надо передать в функцию имя таблицы и опциональный аргумент определяющий условие where . В условии следующим за ключевым словом WHERE следует уточнение: удалить строку, строки или всю таблицу. Если условие where опущено, то будут удалены все строки. Затем составляется запрос delete и следует выполнение запроса.

PHP

   /*   * Удаяем таблицу или записи удовлетворяющие условию   * Требуемые: таблица (наименование таблицы)   * Опционально: где (условие [column = value]), передаем строкой, например, 'id=4'   */     public function delete($table,$where = null)   {   if($this->tableExists($table))   {   if($where == null)   {   $delete = 'DELETE '.$table;   }   else   {   $delete = 'DELETE FROM '.$table.' WHERE '.$where;   }   $del = @mysql_query($delete);   if($del)   {   return true;   }   else   {   return false;   }   }   else   {   return false;   }   }

Наконец перейдем к нашей последней основной функции. Эта функция служит для обновления строки в БД новой информацией. Данная функция на первый взгляд сложна для понимания, однако, это не совсем так. Мы будем использовать все те же принципы, что и раньше. Например, аргументы будут использоваться для составления запроса update . Также мы проверим наличие таблицы при помощи метода tableExists . Если таблица существует, обновим надлежащую строку. Самая сложная часть, конечно, та, где мы занимаемся составлением запроса update . Поскольку оператор update имеет правило за раз обновлять все строки, нам необходимо учесть это и правильно отрегулировать этот момент. Итак, я решил условие where передавать как простой массив. Первый аргумент в этом массиве — имя столбца, следующий аргумент значений столбца. Таким образом, каждый четный номер (включай 0) соответствует имени колонки, а каждый нечетный номер содержит нечетное значение. Соответствующий код приведен ниже:

PHP

 for($i = 0; $i < count($where); $i++)   {   if($i%2 != 0)   {   if(is_string($where[$i]))   {   if(($i+1) != null)   $where[$i] = '"'.$where[$i].'" AND ';   else   $where[$i] = '"'.$where[$i].'"';   }   }   }   $where = implode($condition,$where);

В следующей секции мы создадим часть update оператора, настраивая переменные. Поскольку вы можете изменить любое числовое значение, я предпочел массив с ключами по названию столбца и новыми значениями. Таким образом, нам останется сделать проверку на тип значения и где нужно поставить запятую. Теперь, когда мы составили две основных части оператора update , завершить составление оператора update не составит труда, код представлен ниже:

PHP

public function update($table,$rows,$where,$condition)   {   if($this->tableExists($table))   {   // Parse the where values   // even values (including 0) contain the where rows   // odd values contain the clauses for the row   for($i = 0; $i < count($where); $i++)   {   if($i%2 != 0)   {   if(is_string($where[$i]))   {   if(($i+1) != null)   $where[$i] = '"'.$where[$i].'" AND ';   else   $where[$i] = '"'.$where[$i].'"';   }   }   }   $where = implode($condition,$where);   $update = 'UPDATE '.$table.' SET ';   $keys = array_keys($rows);   for($i = 0; $i < count($rows); $i++)   {   if(is_string($rows[$keys[$i]]))   {   $update .= $keys[$i].'="'.$rows[$keys[$i]].'"';   }   else   {   $update .= $keys[$i].'='.$rows[$keys[$i]];   }   // Parse to add commas   if($i != count($rows)-1)   {   $update .= ',';   }   }   $update .= ' WHERE '.$where;   $query = @mysql_query($update);   if($query)   {   return true;   }   else   {   return false;   }   }   else   {   return false;   }   }

Итак, мы закончили создание последней функции и наш класс для работы с CRUD можно считать законченным. Теперь вы можете создавать новые записи, читать отдельные записи из БД, обновлять записи и удалять. Кроме того, начав повторно использовать данный класс, вы обнаружите, что существенно экономите время и строчки код. То есть вы почувствуете эффективность и преимущество ООП.

Использование

Итак, мы создали наш класс, но как его использовать? Тут все просто. Давайте начнем с создания простой БД, в которой протестируем наш класс. Я создал базу данных test и составил простой mysql оператор. Вы можете поместить его в любую БД.

Первая строка закомментирована, так как она не всегда необходима. Если вам необходимо запустить предыдущий код более одного раза, вам потребуется раскомментировать первую строку, чтобы быть уверенным, что таблица создана.

Теперь, когда наша таблица создана и заполнена, самое время запустить несколько простых запросов.

PHP

<?php  include('crud.php');  $db = new Database();  $db->connect();  $db->select('mysqlcrud');  $res = $db->getResult();  print_r($res);  ?>

Если все сделано корректно, вы увидите следующие:

Аналогичным образом мы можем запустить запрос на обновление и вывести результаты.

PHP

<?php;  $db->update('mysqlcrud',array('name'=>'Changed!'),array('id',1),"=");  $db->update('mysqlcrud',array('name'=>'Changed2!'),array('id',2),"=");  $res = $db->getResult();  print_r($res);  ?>

На выходе:

Теперь просто вставим запись:

PHP

<?php;  $db->insert('mysqlcrud',array(3,"Name 4","this@wasinsert.ed"));  $res = $db->getResult();  print_r($res);  ?>

Источник

dnzl.ru


You May Also Like

About the Author: admind

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.