| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> |
| <!-- |
| Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. |
| --> |
| <html> |
| <head> |
| <title>Создание приложения на основе базы данных на языке PHP. Оптимизация кода PHP. Реорганизация. Файлы Include. Функции доступа к базе данных MySQL</title> |
| <meta name="KEYWORDS" content="CRUD, Update, Delete, MySQL, PHP, NetBeans"> |
| <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> |
| <meta name="DESCRIPTION" content="Creating a Database Driven Application With PHP. Optimizing PHP code. Refactoring. Include files. MySQL Database access functions" > |
| <link rel="stylesheet" type="text/css" href="../../../netbeans.css" media="screen"> |
| </head> |
| <body> |
| <h1>Создание приложения на основе базы данных на языке PHP </h1> |
| <h1>Урок 4: Оптимизация кода путем добавления классов и объектов</h1> |
| <div style="margin-left:-3px"> |
| <div class="feedback-box margin-around float-left" style="margin-right:15px"> |
| <h4>Содержание учебного курса.</h4> |
| <ol start="0"> |
| <li><a href="wish-list-tutorial-main-page.html">Создание приложения на основе базы данных с помощью языка PHP – главная страница</a></li> |
| <li><p>Создание базы данных</p> <ol type="a"><li><a href="wish-list-lesson1.html">Создание базы данных MySQL</a></li> |
| <li><a href="wish-list-oracle-lesson1.html">Создание таблиц базы данных Oracle</a></li> |
| </ol></li> |
| <li><a href="wish-list-lesson2.html">Проектирование приложения. Чтение из базы данных</a></li> |
| <li><a href="wish-list-lesson3.html">Создание нового пользователя приложения</a></li> |
| <li><p><b>=> Оптимизация кода</b></p> |
| <ul> |
| <li><a href="#previousLessonSourceCode">Исходный код приложения из предыдущего урока</a></li> |
| <li><a href="#createDbPhpFile">Создание файла db.php</a></li> |
| <li><a href="#wishDBClass">Создание класса WishDB</a></li> |
| <li><a href="#instantiate-wishdb">Создание экземпляров класса WishDB</a></li> |
| <li><a href="#wishdb-constructor">Добавление конструктора к классу WishDB</a></li> |
| <li><a href="#includedFunctions">Функции класса WishDB</a> |
| <ul> |
| <li><a href="#getIDByName">Функция get_wisherID_by_name</a></li> |
| <li><a href="#getWishesByID">Функция get_wishes_by_wisher_id</a></li> |
| <li><a href="#createWisher">Функция create_wisher</a></li> |
| </ul> |
| </li> |
| <li><a href="#refactoring">Реорганизация кода приложения</a> |
| <ul> |
| <li><a href="#refactoringWishlistFile">Реорганизация файла wishlist.php</a></li> |
| <li><a href="#refactoringCreateNewWisher">Реорганизация файла createNewWisher.php</a></li> |
| </ul> |
| </li> |
| <li><a href="#lessonResultSourceCode">Исходный код приложения на момент завершения текущего урока</a></li> |
| </ul> |
| </li> |
| <li><a href="wish-list-lesson5.html">Добавление функций безопасности. Реализация входа пользователя в приложение</a></li> |
| <li><a href="wish-list-lesson6.html">Добавление к базе данных новых желаний</a></li> |
| <li><a href="wish-list-lesson7.html">Обновление и удаление записей в базе данных</a></li> |
| <li><a href="wish-list-lesson8.html">Усовершенствование внешнего вида приложения с использованием технологии CSS</a></li> |
| <li><a href="wish-list-lesson9.html">Развертывание приложения на удаленном веб-сервере</a></li> |
| </ol> |
| </div> |
| </div> |
| <img alt="Содержимое на этой странице применимо к IDE NetBeans 7.2, 7.3, 7.4 и 8.0" class="stamp" src="../../../images_www/articles/73/netbeans-stamp-80-74-73.png" title="Содержимое этой страницы применимо к IDE NetBeans 7.2, 7.3, 7.4 и 8.0"> |
| <p>В этом уроке рассматриваются способы оптимизации кода, позволяющие упростить поддержку этого кода в дальнейшем. Данная процедура затрагивает файлы <tt>createNewWisher.php</tt> и <tt>wishlist.php</tt>. Кроме того, создается новый файл под названием <tt>db.php</tt>.</p> |
| <p>Код приложения содержит несколько похожих блоков с запросами к базе данных. Для упрощения чтения и поддержки кода в будущем можно извлечь эти блоки, реализовать их в качестве функций отдельного класса <tt>WishDB</tt> и поместить текст <tt>WishDB</tt> в файл <tt>db.php</tt>. Впоследствии можно включить файл <tt>db.php</tt> в любой файл PHP и использовать любую <a href="#includedFunctions">функцию класса WishDB</a> без дублирования кода. Такой подход гарантирует, что любые изменения в запросах или функциях будут выполнены в одном местоположении, и анализировать весь код приложения не потребуется. </p> |
| <p>При использовании функции класса WishDB не следует изменять значения каких-либо переменных в классе WishDB. Вместо этого необходимо использовать класс в качестве концептуального проекта для создания объекта WishDB и изменять значения переменных в этом объекте. Объект уничтожается при завершении работы. Поскольку значения непосредственно класса WishDB никогда не изменяются, данный класс можно использовать повторно неограниченное число раз. В некоторых случаях может потребоваться одновременно несколько экземпляров класса, а в других случаях будет предпочтителен "одноэкземплярный" класс, имеющий только один экземпляр в любой момент времени. WishDB в данном руководстве представлен как одноэкземплярный класс.</p> |
| <p>Следует отметить, что создание объекта класса обозначается термином "создание экземпляра" этого класса и что объект в данном случае называется "экземпляром" класса. Общий термин, обозначающий программирование с использованием классов и объектов, – "объектно-ориентированное программирование" (ООП). В PHP 5 используется сложная модель ООП. См. <a href="http://us3.php.net/zend-engine-2.php" target="_blank">php.net</a> для получения дополнительной информации.</p> |
| <p>В данном руководстве вы перемещаете функциональность вызова базы данных из отдельных файлов РНР в класс WishDB. Пользователи MySQL также заменяют процедурные вызовы <tt>mysqli</tt> объектно-ориентированными. Это соответствует новой объектно-ориентированной структуре приложения.</p> |
| <p>Текущий документ является частью краткого учебного курса "Создание приложения CRUD в IDE NetBeans для PHP". </p> |
| <br style="clear:left"> |
| <h2><a name="previousLessonSourceCode"></a>Исходный код приложения из предыдущего урока</h2> |
| <p>Для пользователей MySQL: перейдите по <a href="https://netbeans.org/files/documents/4/1929/lesson3.zip" target="_blank">этой ссылке</a> для загрузки исходного кода, описывающего состояние проекта на момент завершения предыдущего урока. </p> |
| <p>Для пользователей Oracle Database: щелкните <a href="https://netbeans.org/projects/www/downloads/download/php%252Foracle-lesson3.zip" target="_blank">здесь</a> для загрузки исходного кода, отражающего состояние проекта по завершении предыдущего урока.</p> |
| <h2><a name="createDbPhpFile"></a>Создание файла db.php</h2> |
| <p>Создайте новую подпапку в папке "Исходные файлы". Дайте папке имя Includes. Создайте новый файл под именем db.php и поместите его в папку Includes. Позже вы сможете добавлять в эту папку файлы, которые будут включаться в другие РНР-файлы. </p> |
| <p><b>Чтобы создать файл db.php в новой папке, сделайте следующее:</b></p> |
| <ol> |
| <li>Щелкните правой кнопкой мыши узел "Source Files" и выберите "New > Folder" в контекстном меню. Откроется диалоговое окно "Новая папка" </li> |
| <li>В поле "Имя папки" введите Includes. Затем нажмите кнопку "Готово".</li> |
| |
| <li>Щелкните правой кнопкой мыши узел "Includes" и выберите "New > PHP File" в контекстном меню. Откроется диалоговое окно "Новый файл РНР".</li> |
| <li>В поле "Имя файла" введите db. Затем нажмите кнопку "Готово". </li> |
| </ol> |
| <h2><a name="wishDBClass"></a>Создание класса WishDB</h2> |
| <p>Для создания класса WishDB необходимо инициализировать переменные класса и реализовать конструктор класса. Пользователи MySQL, обратите внимание, что класс WishDB <em>расширяет</em> <tt>mysqli</tt>. Это означает, что WishDB <em>наследует</em> функции и другие характеристики класса PHP mysqli. Вы убедитесь в важности этого при добавлении функций <tt>mysqli </tt> к классу.</p> |
| <p>Откройте файл db.php и создайте класс WishDB. В данном классе объявите переменные настройки базы данных для хранения имени и пароля собственника базы данных (пользователя), имени и машины размещения базы данных. Все объявления переменных являются закрытыми: это означает, что начальные значения в этих объявлениях недоступны вне класса WishDB (см. <a href="http://us3.php.net/manual/en/language.oop5.visibility.php" target="_blank">php.net</a>). Вы также объявляете закрытую <em> статическую переменную</em> <tt>$instance</tt>, которая хранит экземпляр WishDB. Ключевое слово "статический" означает, что функции в классе имеют доступ к переменной даже при отсутствии экземпляра класса.</p> |
| <p><strong>Для базы данных MySQL:</strong></p> |
| <pre class="examplecode">class WishDB extends mysqli { |
| |
| |
| // single instance of self shared among all instances |
| private static $instance = null; |
| |
| |
| // db connection config vars |
| private $user = "phpuser"; |
| private $pass = "phpuserpw"; |
| private $dbName = "wishlist"; |
| private $dbHost = "localhost"; |
| }</pre> |
| <p><strong>Для базы данных Oracle:</strong></p> |
| <pre class="examplecode"> |
| class WishDB {<br><br> |
| |
| // single instance of self shared among all instances |
| private static $instance = null;<br><br> |
| |
| // db connection config vars |
| private $user = "phpuser"; |
| private $pass = "phpuserpw"; |
| private $dbName = "wishlist"; |
| private $dbHost = "localhost/XE"; |
| private $con = null;<br><br> |
| } </pre> |
| <h2 id="instantiate-wishdb">Создание экземпляров класса WishDB</h2> |
| <p>При использовании функций класса WishDB в других файлах PHP должна быть вызвана функция, позволяющая создать объект ("создать экземпляр") класса WishDB. WishDB разработан в качестве <a href="http://www.phpclasses.org/browse/package/1151.html" target="_blank">одноэкземплярного класса</a>; это означает, что в любой определенный момент времени может существовать только один экземпляр класса. Поэтому рекомендуется предотвращать создание экземпляра WishDB, которое осуществляется извне и способствует появлению дублирующихся экземпляров.</p> |
| <p>Внутри класса WishDB введите или вставьте следующий код:</p> |
| <pre class="examplecode"> //This method must be static, and must return an instance of the object if the object |
| //does not already exist. |
| public static function getInstance() { |
| if (!self::$instance instanceof self) { |
| self::$instance = new self; |
| } |
| return self::$instance; |
| } |
| |
| // The clone and wakeup methods prevents external instantiation of copies of the Singleton class, |
| // thus eliminating the possibility of duplicate objects. |
| public function __clone() { |
| trigger_error('Clone is not allowed.', E_USER_ERROR); |
| } |
| public function __wakeup() { |
| trigger_error('Deserializing is not allowed.', E_USER_ERROR); |
| }</pre> |
| <p>Функция <tt>getInstance</tt> является общедоступной и статической. Общедоступность означает возможность свободного доступа извне класса. Статическая функция доступна даже в том случае, если для класса не было создано экземпляров. Поскольку функция <tt>getInstance</tt> вызывается для создания экземпляров класса, она является статической. Обратите внимание, что эта функция имеет доступ к статической переменной<tt>$instance</tt> и устанавливает ее значение как экземпляр класса. |
| |
| <p>Двойное двоеточие (::), или "оператор разрешения диапазона" (Scope Resolution Operator), и ключевое слово <tt>self</tt> используются для получения доступа к статическим функциям. <tt>Self</tt> в рамках определения класса используется в качестве ссылки на данный класс. Если двойное двоеточие находится вне определения класса, вместо <tt>self</tt> используется имя класса. См. ресурс <a href="http://us3.php.net/manual/en/language.oop5.paamayim-nekudotayim.php" target="_blank">php.net для получения информации об операции разрешения диапазона</a>. |
| <h2 id="wishdb-constructor">Добавление конструктора к классу WishDB</h2> |
| <p>Класс может содержать в себе специальный метод, известный как "конструктор", который выполняется автоматически каждый раз при создании экземпляра этого класса. В данном руководстве рассматривается добавление к классу WishDB конструктора, который подключается к базе данных каждый раз при создании экземпляра WishDB.</p> |
| <p>Добавьте к WishDB следующий код:</p> |
| <p><b>Для базы данных MySQL</b></p> |
| <pre class="examplecode">// private constructor<br>private function __construct() {<br> parent::__construct($this->dbHost, $this->user, $this->pass, $this->dbName);<br> if (mysqli_connect_error()) {<br> exit('Connect Error (' . mysqli_connect_errno() . ') '<br> . mysqli_connect_error());<br> }<br> parent::set_charset('utf-8');<br>}</pre> |
| <p><b>Для базы данных Oracle</b></p> |
| <pre class="examplecode">// private constructor |
| private function __construct() { |
| $this->con = oci_connect($this->user, $this->pass, $this->dbHost); |
| if (!$this->con) { |
| $m = oci_error(); |
| echo $m['message'], "\n"; |
| exit; |
| } |
| }</pre> |
| <p>Следует учитывать, что вместо переменных <tt>$con</tt>, <tt>$dbHost</tt>, <tt>$user</tt> или <tt>$pass</tt> используется псевдопеременная <tt>$this</tt>. Псевдопеременная <tt>$this</tt> используется при вызове метода внутри контекста объекта. Она ссылается на значение переменной внутри этого объекта.</p> |
| <h2><a id="includedFunctions" name="includedFunctions"></a>Функции класса WishDB </h2> |
| <p>В этом уроке рассматривается реализация следующих функций класса WishDB:</p> |
| <ul> |
| <li><a href="#getIDByName">get_wisher_id_by_name</a> для извлечения идентификатора пользователя на основе имени </li> |
| <li><a href="#getWishesByID">get_wishes_by_wisher_id</a> для извлечения списка пожеланий "Wish list", принадлежащего определенному пользователю с соответствующим идентификатором </li> |
| <li><a href="#createWisher">create_wisher</a> для добавления нового пользователя в таблицу "Wishers". </li> |
| </ul> |
| <div class="indent"><h3><a id="getIDByName" name="getIDByName"></a>Функция get_wisher_id_by_name</h3> |
| Эта функция возвращает идентификатор пользователя, а в качестве входного параметра для ее выполнения требуется имя пользователя. <br> |
| <p> |
| После функции WishDB введите или вставьте следующую функцию в класс WishDB:</p> |
| <p><b>Для базы данных MySQL</b></p> |
| <pre class="examplecode">public function get_wisher_id_by_name($name) {<br> |
| $name = $this->real_escape_string($name);<br> |
| $wisher = $this->query("SELECT id FROM wishers WHERE name = '"<br> |
| . $name . "'"); |
| if ($wisher->num_rows > 0){<br> $row = $wisher->fetch_row();<br> return $row[0];<br> } else<br> return null; |
| }</pre> |
| <p><b>Для базы данных Oracle</b></p> |
| <pre class="examplecode">public function get_wisher_id_by_name($name) { |
| $query = "SELECT id FROM wishers WHERE name = :user_bv"; |
| $stid = oci_parse($this->con, $query); |
| oci_bind_by_name($stid, ':user_bv', $name); |
| oci_execute($stid); |
| //Because user is a unique value I only expect one row |
| $row = oci_fetch_array($stid, OCI_ASSOC);<br> if ($row) <br> return $row["ID"];<br> else<br> return null; |
| }</pre> |
| Блок кода выполняет запрос <tt>SELECT ID FROM wishers WHERE name = [переменная для имени пожелания]</tt>. Результат запроса - массив идентификаторов из записей, соответствующих запросу. Если массив не пустой, это по умолчанию означает, что он содержит один элемент, поскольку при создании таблицы имя поля было определено как UNIQUE. В этом случае функция возвращает первый элемент массива <tt>$result</tt> (элемент под номером ноль). Если массив пуст, функция возвращает значение "null". |
| <p class="notes"><b>Примечание к безопасности.</b> Для базы данных MySQL строка <tt>$name </tt> используется с с escape-символом для предотвращения атак SQL-инъекций. См. <a href="http://en.wikipedia.org/wiki/SQL_injection" target="_blank">статью энциклопедии Wikipedia о введении SQL </a> и <a href="http://us3.php.net/mysql_real_escape_string" target="_blank">документацию mysql_real_escape_string</a>. Несмотря на то, что в контексте этого руководства риск возникновения опасных атак внедрения SQL маловероятен, рекомендуется исключить из участия в запросах MySQL такие строки, которые могли бы быть подвержены подобной атаке. База данных Oracle избегает данной проблемы, используя связанные переменные.</p> |
| <h3><a id="getWishesByID" name="getWishesByID"></a>Функция get_wishes_by_wisher_id</h3> |
| <p>Эта функция возвращает зарегистрированные пожелания пользователя, и для ее выполнения в качестве входного параметра требуется идентификатор пользователя. </p> |
| <p>Введите следующий блок кода:</p> |
| <p><b>Для базы данных MySQL</b></p> |
| <pre class="examplecode">public function get_wishes_by_wisher_id($wisherID) {<br> return $this->query("SELECT id, description, due_date FROM wishes WHERE wisher_id=" . $wisherID);<br>}</pre> |
| <p><b>Для базы данных Oracle</b></p> |
| <pre class="examplecode">public function get_wishes_by_wisher_id($wisherID) { |
| $query = "SELECT id, description, due_date FROM wishes WHERE wisher_id = :id_bv"; |
| $stid = oci_parse($this->con, $query); |
| oci_bind_by_name($stid, ":id_bv", $wisherID); |
| oci_execute($stid); |
| return $stid; |
| }</pre> |
| <p>Блок кода выполняет запрос <tt>"SELECT id, description, due_date FROM wishes WHERE wisherID=" . $wisherID</tt> и возвращает набор результатов, который является массивом записей, соответствующих запросу. (База данных Oracle использует связанную переменную для повышения производительности базы данных и уровня безопасности). Выделение выполняется с помощью wisherID, который является внешним ключом для таблицы <tt>wishes</tt>. </p> |
| <p class="notes"><b>Примечание.</b> Значение <tt>идентификатора</tt> не требуется до занятия 7.</p> |
| <h3><a id="createWisher" name="createWisher"></a>Функция create_wisher</h3> |
| <p>Функция создает новую запись в таблице "Wishers". Эта функция не возвращает каких-либо данных, и в качестве входных параметров для ее выполнения требуется имя и пароль нового пользователя.</p> |
| Введите следующий блок кода: |
| <p><b>Для базы данных MySQL</b></p> |
| <pre class="examplecode">public function create_wisher ($name, $password){ |
| $name = $this->real_escape_string($name);<br> $password = $this->real_escape_string($password);<br> $this->query("INSERT INTO wishers (name, password) VALUES ('" . $name . "', '" . $password . "')"); |
| }</pre> |
| <p><b>Для базы данных Oracle</b></p> |
| <pre class="examplecode">public function create_wisher($name, $password) { |
| $query = "INSERT INTO wishers (name, password) VALUES (:user_bv, :pwd_bv)"; |
| $stid = oci_parse($this->con, $query); |
| oci_bind_by_name($stid, ':user_bv', $name); |
| oci_bind_by_name($stid, ':pwd_bv', $password); |
| oci_execute($stid); |
| }</pre> |
| Блок кода выполняет запрос <tt>"INSERT wishers (Name, Password) VALUES ([переменные представляющие имя и пароль нового пожелания])</tt>. При выполнении запроса добавляется новая запись в таблицу "Wishers" с полями "name" и "password", заполненными значениями <tt>$name</tt> и <tt>$password</tt> соответственно. </div> |
| <h2><a name="refactoring"></a>Реорганизация кода приложения</h2> |
| <p>Теперь при наличии отдельного класса для работы с базой данных дублированные блоки можно заменить вызовами соответствующих функций из этого класса. Это помогает в дальнейшем избежать ошибок и противоречий в написании кода. Усовершенствование кода, не оказывающее влияния на функциональные возможности, называется "реорганизацией".</p> |
| <div class="indent"> |
| <h3><a name="refactoringWishlistFile"></a>Реорганизация файла wishlist.php </h3> |
| Начнем с файла wishlist.php, поскольку он небольшой и дает возможность представить оптимизацию более иллюстративно. |
| <ol> |
| <li>В верхней части блока <? php? > введите следующую строку, делающую возможным использование файла <tt>db.php</tt>: |
| <pre class="examplecode">require_once("Includes/db.php");</pre> |
| </li> |
| |
| <li>Замените код, который подключается к базе данных и получает идентификатор пожелания, вызовом функции <tt>get_wisher_id_by_name</tt>. |
| <p>Для <b>базы данных MySQL </b> вы заменяете следующий код: |
| <pre class="examplecode"><del>$con = mysqli_connect("localhost", "phpuser", "phpuserpw"); |
| if (!$con) { |
| exit('Connect Error (' . mysqli_connect_errno() . ') ' |
| . mysqli_connect_error()); |
| } |
| //set the default client character set |
| mysqli_set_charset($con, 'utf-8'); |
| |
| mysqli_select_db($con, "wishlist"); |
| $user = mysqli_real_escape_string($con, $_GET['user']); |
| $wisher = mysqli_query($con, "SELECT id FROM wishers WHERE name='" . $user . "'"); |
| if (mysqli_num_rows($wisher) < 1) { |
| exit("The person " . $_GET['user'] . " is not found. Please check the spelling and try again"); |
| } |
| $row = mysqli_fetch_row($wisher);<br>$wisherID = $row[0]; |
| mysqli_free_result($wisher);</del><br><br> |
| <b>$wisherID = WishDB::getInstance()->get_wisher_id_by_name($_GET["user"]); |
| if (!$wisherID) { |
| exit("The person " .$_GET["user"]. " is not found. Please check the spelling and try again" ); |
| }</b></pre> |
| <p>Для <b>базы данных Oracle </b> вы заменяете следующий код:</p> |
| <pre class="examplecode"><del>$con = oci_connect("phpuser", "phpuserpw", "localhost/XE", "AL32UTF8"); |
| if (!$con) { |
| $m = oci_error(); |
| echo $m['message'], "\n"; |
| exit; |
| } |
| $query = "SELECT id FROM wishers WHERE name = :user_bv"; |
| $stid = oci_parse($con, $query); |
| $user = $_GET["user"]; |
| |
| oci_bind_by_name($stid, ':user_bv', $user); |
| oci_execute($stid); |
| |
| //Because user is a unique value I only expect one row<br> |
| $row = oci_fetch_array($stid, OCI_ASSOC); |
| if (!$row) { |
| echo("The person " . $user . " is not found. Please check the spelling and try again" );<br> exit;<br> |
| } |
| $wisherID = $row["ID"]; </del> |
| <br> |
| <b>$wisherID = WishDB::getInstance()->get_wisher_id_by_name($_GET["user"]); |
| if (!$wisherID) { |
| exit("The person " .$_GET["user"]. " is not found. Please check the spelling and try again" ); |
| }</b></pre> |
| <p>Новый код сначала вызывает функцию <tt>getInstance</tt> в WishDB. Функция <tt>getInstance</tt> возвращает экземпляр WishDB, а код вызывает функцию <tt>get_wisher_id_by_name</tt> в пределах данного экземпляра. Если требуемое пожелание в базе данных не найдено, код завершает процесс и отображает сообщение об ошибке.</p><p>Для открытия подключения к базе данных наличие кода не является необходимым. Открытие подключения выполняется конструктором класса WishDB. Если имя и/или пароль изменяются, необходимо обновить только соответствующие переменные класса WishDB.</p> |
| </li> |
| <li>Замените код, который получает пожелания для автора пожеланий, идентифицированного с помощью кода, кодом, который вызывает функцию <tt>get_wishes_by_wisher_id</tt>. |
| <p>Для <b>базы данных MySQL </b> вы заменяете следующий код: |
| <pre class="examplecode"><del>$result = mysqli_query($con, "SELECT description, due_date FROM wishes WHERE wisher_id=". $wisherID);</del> |
| |
| <strong>$result = WishDB::getInstance()->get_wishes_by_wisher_id($wisherID);</strong></pre> |
| <p>Для <b>базы данных Oracle </b> вы заменяете следующий код: </p> |
| <pre class="examplecode"><del>$query = "select * from wishes where wisher_id = :id_bv";<br>$stid = oci_parse($con, $query);<br>oci_bind_by_name($stid, ":id_bv", $wisherID);<br>oci_execute($stid);</del> |
| |
| <strong>$stid = WishDB::getInstance()->get_wishes_by_wisher_id($wisherID);</strong></pre> |
| </li> |
| <li>Удалите строку, которая закрывает подключение к базе данных. |
| <pre class="examplecode"> <del>mysqli_close($con);</del> |
| or |
| <del>oci_close($con);</del> </pre> |
| Код не нужен, потому что подключение к базе данных автоматически закрывается при уничтожении объекта WishDB. Однако рекомендуем сохранять код, освобождающий ресурс. Вам необходимо освободить все ресурсы, которые используют подключение, чтобы убедиться в том, что оно закрыто, даже при вызове функции <tt>close</tt> или уничтожении экземпляра с подключением к базе данных.</li> |
| </ol> |
| <h3> </h3> |
| <h3><a name="refactoringCreateNewWisher"></a>Реорганизация файла createNewWisher.php </h3> |
| <p>Реорганизация не оказывает воздействия на форму ввода HTML или код для вывода на экран соответствующих сообщений об ошибках.</p> |
| <ol> |
| <li>В верхней части блока <? php? > введите следующий код, делающий возможным использование файла <tt>db.php</tt>: |
| <pre class="examplecode">require_once("Includes/db.php");</pre> |
| </li> |
| <li>Удалите подтверждения подключения к базе данных (<tt>$dbHost</tt> и пр.). Теперь они находятся в<tt>db.php</tt>.</li> |
| <li>Замените код, который подключается к базе данных и получает идентификатор пожелания, вызовом функции <tt>get_wisher_id_by_name</tt>. |
| <p>Для <b>базы данных MySQL </b> вы заменяете следующий код:</p> |
| <pre class="examplecode"><del> |
| $con = mysqli_connect("localhost", "phpuser", "phpuserpw"); |
| if (!$con) { |
| exit('Connect Error (' . mysqli_connect_errno() . ') ' |
| . mysqli_connect_error()); |
| } |
| //set the default client character set |
| mysqli_set_charset($con, 'utf-8'); |
| |
| |
| <br>/** Check whether a user whose name matches the "user" field already exists */ |
| mysqli_select_db($con, "wishlist"); |
| $user = mysqli_real_escape_string($con, $_POST['user']); |
| $wisher = mysqli_query($con, "SELECT id FROM wishers WHERE name='".$user."'"); |
| $wisherIDnum=mysqli_num_rows($wisher); |
| if ($wisherIDnum) { |
| $userNameIsUnique = false; |
| }</del> |
| <br> |
| <strong>$wisherID = WishDB::getInstance()->get_wisher_id_by_name($_POST["user"]);<br>if ($wisherID) {<br> $userNameIsUnique = false;<br>}</strong></pre> |
| <p>Для <b>базы данных Oracle </b> вы заменяете следующий код: </p> |
| <pre class="examplecode"><del> |
| $con = oci_connect("phpuser", "phpuserpw", "localhost"); |
| if (!$con) { |
| $m = oci_error(); |
| echo $m['message'], "\n"; |
| exit; |
| } |
| $query = "select ID from wishers where name = :user_bv"; |
| $stid = oci_parse($con, $query); |
| $user = $_POST['user']; |
| $wisherID = null; |
| oci_bind_by_name($stid, ':user_bv', $user); |
| oci_execute($stid); |
| |
| //Each user name should be unique. Check if the submitted user already exists. |
| $row = oci_fetch_array($stid, OCI_ASSOC);<br>if ($row) {<br> $wisherID = $row["ID"]; <br>}<br>if ($wisherID != null) {<br> $userNameIsUnique = false;<br>}</del> |
| |
| <strong>$wisherID = WishDB::getInstance()->get_wisher_id_by_name($_POST["user"]);<br>if ($wisherID) {<br> $userNameIsUnique = false;<br>}</strong></pre> |
| |
| Объект <tt>WishDB</tt> существует до тех пор, пока обрабатывается текущая страница. Если обработка завершена или прервана, этот объект уничтожается. Код для открытия подключения к базе данных не является необходимым, поскольку подключение выполняется посредством функции WishDB. Код для закрытия подключения также не является необходимым, поскольку подключение будет закрыто сразу же после уничтожения объекта <tt>WishDB</tt>.</li> |
| <li>Замените код, который вставляет новых авторов пожеланий в базу данных, кодом, который вызывает функцию <tt>create_wisher</tt>. |
| <p>Для <b>базы данных MySQL </b> вы заменяете следующий код:</p> |
| |
| <pre class="examplecode"><del>if (!$userIsEmpty && $userNameIsUnique && !$passwordIsEmpty && !$password2IsEmpty && $passwordIsValid) { |
| $password = mysqli_real_escape_string($con, $_POST["password"]);<br> mysqli_select_db($con, "wishlist");<br> mysqli_query($con, "INSERT wishers (name, password) VALUES ('" . $user . "', '" . $password . "')");<br> mysqli_free_result($wisher);<br> mysqli_close($con);<br> header('Location: editWishList.php');<br> exit;<br>} |
| </del> |
| <strong>if (!$userIsEmpty && $userNameIsUnique && !$passwordIsEmpty && !$password2IsEmpty && $passwordIsValid) {<br> WishDB::getInstance()->create_wisher($_POST["user"], $_POST["password"]);<br> header('Location: editWishList.php' );<br> exit;<br>}</strong></pre> |
| <p>Для <b>базы данных Oracle </b> вы заменяете следующий код: </p> |
| <pre class="examplecode"><del> |
| if (!$userIsEmpty && $userNameIsUnique && !$passwordIsEmpty && !$password2IsEmpty && $passwordIsValid) { |
| $query = "INSERT INTO wishers (name, password) VALUES (:user_bv, :pwd_bv)"; |
| $stid = oci_parse($con, $query); |
| $pwd = $_POST['password']; |
| oci_bind_by_name($stid, ':user_bv', $user); |
| oci_bind_by_name($stid, ':pwd_bv', $pwd); |
| oci_execute($stid); |
| oci_close($con); |
| header('Location: editWishList.php'); |
| exit; |
| }</del> |
| |
| |
| <strong>if (!$userIsEmpty && $userNameIsUnique && !$passwordIsEmpty && !$password2IsEmpty && $passwordIsValid) {<br> WishDB::getInstance()->create_wisher($_POST["user"], $_POST["password"]);<br> header('Location: editWishList.php' );<br> exit;<br>}</strong></pre> |
| </li> |
| </ol> |
| </div> |
| |
| <h2><a name="lessonResultSourceCode"></a>Исходный код приложения на момент завершения текущего урока </h2> |
| <p>Для пользователей MySQL: щелкните <a href="https://netbeans.org/projects/www/downloads/download/php%252Flesson4.zip" target="_blank">сюда</a> для загрузки исходного кода, отражающего состояние проекта по завершении данного урока.</p> |
| <p>Для пользователей Oracle Database: щелкните <a href="https://netbeans.org/projects/www/downloads/download/php%252Foracle-lesson4.zip" target="_blank">здесь</a> для загрузки исходного кода, отражающего состояние проекта по завершении данного урока.</p> |
| <h2><a name="nextSteps"></a>Что дальше?</h2> |
| <p> |
| <a href="wish-list-lesson3.html"><<Предыдущий урок</a><br> <br> <a href="wish-list-lesson5.html">Следующий урок >></a><br> <br> <a href="wish-list-tutorial-main-page.html">Назад на главную страницу руководства</a><br> <br> |
| </p> |
| <h2><a name="usefulLinks"></a>Полезные ссылки</h2> |
| <p>Дополнительная информация об использовании классов в PHP:</p> |
| <ul> |
| <li><a href="http://us3.php.net/manual/en/language.oop5.php" target="_blank">Классы и объекты</a> </li> |
| </ul> |
| <p>Дополнительная информация о реорганизации кода PHP: </p> |
| <ul> |
| <li><a href="http://www.slideshare.net/spriebsch/seven-steps-to-better-php-code-presentation/" target="_blank">Семь действий по усовершенствованию кода PHP</a></li> |
| <li> <a href="http://www.dokeos.com/wiki/index.php/Refactoring" target="_blank">Реорганизация PHP</a></li> |
| </ul> |
| <br> |
| <div class="feedback-box" ><a href="/about/contact_form.html?to=3&subject=Feedback:%20PHP%20Wish%20List%20CRUD%204:%20Optimizing%20Code">Отправить отзыв по этому учебному курсу</a></div> |
| <br style="clear:both;" > |
| <p>Для отправки комментариев и предложений, получения поддержки и новостей о последних разработках, связанных с PHP IDE NetBeans <a href="../../../community/lists/top.html">присоединяйтесь к списку рассылки users@php.netbeans.org</a>.</p> |
| <p><a href="../../trails/php.html">Возврат к учебной карте PHP</a><br> |
| </p> |
| </body> |
| </html> |