Използване на PHP обекти с данни

  • Необходими знания: Полезни са някои познания за PHP и SQL
  • Изисква: Уеб сървър (като Apache) с PHP зареден и релационна система за управление на база данни, способна на PDO свързаност (като MySQL); ODBC и Doctrine 2 са допълнителни екстри
  • Време на проекта : 1-3 часа (или повече, в зависимост от Вашия необичаен учебен път и капацитет)
  • Изходен файл

Тази статия се появи за първи път в брой 231 на .net magazine.

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

Популярна система за управление на бази данни, използвана заедно с езика PHP, е базата данни MySQL, като Microsoft SQL, PostgreSQL и Oracle също са доста често срещани. PHP групата от разработчици първоначално улесни свързването между PHP и системите за бази данни, използвайки специфични за системата от бази данни функции като:



MySQL: ресурс mysql_query (низ $ query [, ресурс $ link_identifier])
Microsoft SQL: смесен mssql_query (низ $ query [, ресурс $ link_identifier [,
int $ batch_size = 0]])
PostgreSQL: ресурс pg_query ([връзка с ресурс $], низ $ заявка)
База данни на Oracle: bool oci_execute (ресурс $ statement [, int $ mode = OCI_
COMMIT_ON_SUCCESS])



лаптоп hp walmart черен петък 2016

Както можете да видите от дефинициите, те нямат стандартизирана форма, така че ако трябва да промените системата си от Oracle на MySQL, ще трябва да работите с кода си и да промените начина на свързване с вашата база данни. Това също е трън в изучаването на свързаността с бази данни в PHP: не можете просто да прехвърлите знанията си, например от PostgreSQL в Microsoft SQL.

01. Философията на PHP Data Objects (PDO)

За щастие в PHP съществува спасител за свързване на база данни - и това е под формата на трибуквеното съкращение PDO, което означава PHP Data Objects. Идеята на PDO библиотеката е, че тя осигурява стандартизирана основа, върху която можете да се свържете с всяка система за управление на релационни бази данни (RDBMS), която може да бъде заявена с помощта на SQL.



С малко късмет вашият скрипт за създаване на PDO трябва да създаде валидна таблица, като тази по-горе, във вашата база данни

С малко късмет вашият скрипт за създаване на PDO трябва да създаде валидна таблица, като тази по-горе, във вашата база данни

По време на писането това включва CUBRID, Firebird, Interbase, IBM DB2, Informix, Microsoft SQL Server, MySQL, Oracle, PostgreSQL, SQLite, 4D - и всяка база данни, която е свързана чрез ODBC.

Вземайки бърз концептуален пример за промените, по-рано щяхме да видим:

_query ($ sql);



Сега виждаме стандартизиран набор от функции, който изглежда малко по следния начин:

$ conn-> заявка ($ sql);

Но това е напълно достатъчно теория за сега - нека да разгледаме тази мощна библиотека в действие! Има два различни аспекта на PDO, първият е връзката - което е очевидно задължителен елемент - докато втората страна е елементът за заявка.

02. Свързване със система за управление на база данни

Преди да заявим каквито и да е данни, трябва да се свържем с вече инсталирана и настроена система за управление на база данни. Ще се свържем с база данни MySQL, която работи на localhost, за първия пример:

PDO ('mysql: host = localhost; dbname = yourdbname', 'потребителско име', 'парола');

Нека сравним това с свързването към база данни PostgreSQL:

w PDO ('pgsql: host = localhost; dbname = yourdbname', 'потребителско име', 'парола');

Връзките са стандартизирани благодарение на първия пример, използващ същата функция, докато вторият използва системата за стандартизирано име на източник на данни (DSN). Можете да започнете да виждате колко лесно е, ако просто искате да превключите от една система за управление на база данни на друга.

Drupal 7 има PDO зад своите слоеве за абстракция на база данни. Официалната документация на Drupal за тях е чудесен начин да научите повече за интеграцията

Drupal 7 има PDO зад своите слоеве за абстракция на база данни. Официалната документация на Drupal за тях е чудесен начин да научите повече за интеграцията

03. Запитване и четене на резултати

Заявките за данни първоначално са по-интересни от създаването на данни и тъй като това е урок за свързване на данни, а не за SQL, ще преминем направо към заявки и ще посетим създаването, вмъкването, актуализирането и изтриването по-късно.

Ще предположим, че имаме таблица, наречена профил , който изброява различни подробности за потребителите на хипотетично уеб приложение. Като пример, нека стартираме бързо извличане на профил в SQL чрез PDO и след това просто да изведем пълните имена. Забележете как функцията за заявка може да се използва като итератор - функция, която съхранява указател в паметта към текущия елемент на масив (или набор от резултати в този случай). Когато това се комбинира с a за всеки цикъл позволява бърз и лесен метод за достъп до редове:

$ conn = new $ conn = new $ conn = new $ conn = neforeach ($ conn-> query ('SELECT * FROM profile') като $ row) echo
$ row ['fullname'];

Разбира се, това е бързо и лесно, но едва ли някога искаме да извлечем всички редове; затова нека добавим някои условни условия чрез променливо впръскване. Тук използваме по-надежден метод за заявки, който подготвя заявката и инжектира променливите:

$ query = $ conn-> подгответе ('SELECT * FROM profile WHERE потребителско име =
: потребителско име ГРАНИЦА 1 ');
$ query-> bindParam (': потребителско име', 'knightofarcadia');
$ query-> execute ();
$ profile = $ query> fetch (PDO :: FETCH_ASSOC);
echo $ profile ['fullname'];

Кодът по-горе ще ограничи търсенето в таблицата с профили само до един профил с потребителско име vghtofarcadia . Подобно на нашия първи пример, той просто ще отпечата пълното име след това - но със сигурност можете да си представите изграждането на цяла XHTML страница, на която данните им се предават.

Тукан Сам е талисманът, за който зърнени закуски

Библиотеката PHP Data Objects помага на HipHop Engine на Facebook, която може да намали използването на процесора на своите уеб сървъри с до 50%

Библиотеката PHP Data Objects помага на HipHop Engine на Facebook, която може да намали използването на процесора на своите уеб сървъри с до 50%

Възможно е обаче да имаме повече от един ред, върнат в нашата заявка, и следователно имаме възможността да използваме донеси метод като итератор. Тук виждаме различна заявка, която връща набор от резултати с множество редове:

$ query = $ conn-> подгответе ('SELECT * FROM profile WHERE hometown =: hometown');
$ query-> bindParam (': родния град', 'Wessex');
$ query-> execute ();
foreach ($ query-> fetch (PDO :: FETCH_ASSOC) като $ ред) {
echo $ row ['fullname'];
}

Горният екземпляр ще търси в базата данни с профили и ще върне всички профили, които имат роден град настроен на Уесекс . The донеси След това се използва метод за връщане на всички тези резултати и за ясен пример можем просто да разпечатаме пълното име на екран - въпреки че това може да е по-сложна операция на XHTML страница.

04. Създаване

Сега, въпреки че бих се застъпил за създаването на структура на базата данни, която се извършва в SQL директно в системата за управление на базата данни, е възможно динамично да се създават таблици на базата данни с помощта на SQL, изготвена от PDO:

$ createql = $ conn-> подгответе ('СЪЗДАЙТЕ профили на ТАБЛИЦА (потребителско име VARCHAR (64), пълно име VARCHAR (128), родния град VARCHAR (128)'));
$ conn-> заявка ($ createql);

Моля, не забравяйте, че заявка object в този случай няма да върне нищо ценно, защото е команда за създаване. Както вече споменахме, струва си да се опитаме да избягваме използването на динамично създаване на таблици по този начин в уеб приложение, въпреки че мога да си представя, че се използва в уеб базирани системи (като веднъж изпълнени) (като сървърни инсталатори на уеб приложения), тъй като както и в прости не-базирани сървърни скриптове.

Ето обектен модел, който съответства на примерния PHP код, използван в този урок

Ето обектен модел, който съответства на примерния PHP код, използван в този урок

05. Вмъкване

Вмъкването на данни е много важно в динамична система, и особено в съвременните системи Web 2.0 и Web 3.0, които са ориентирани към сътрудничество и сътрудничество - как могат да си сътрудничат потребителите, ако нямат възможност да съхраняват и споделят данни? Следователно, нека вмъкнем някои данни в нашата таблица с профили по следния начин:

$ insertsql = 'ВЪВЕЖДАНЕ В профили (потребителско име, пълно име, роден град) ЦЕННОСТИ (: потребителско име,: пълно име,: роден град)';
$ query = $ conn-> подгответе ($ insertsql);
$ query-> bindParam (': потребителско име', 'knightofarcadia');
$ query-> bindParam (': пълно име', 'Артър Пендрагон');
$ query-> bindParam (': родния град', 'Wessex');
$ query-> execute ();

Като заявка функция при създаването на таблици, това изпълни функция няма да върне нищо ценно, защото това е просто команда за вмъкване в базата данни. Също така ще забележите, че използваме техниката „подготвяне, свързване и изпълнение“, за да инжектираме нашите променливи в нашия SQL.

06. Актуализиране

Актуализирането, като вмъкване и изтриване, е от решаващо значение в съвместната система и PDO улеснява това. Актуализирането е доста подобно на вмъкването:

$ query = $ conn-> подготви ('АКТУАЛИЗИРАНЕ на профили НАСТРОЙВАЙ пълното име =: пълното име КЪДЕ
потребителско име =: потребителско име ');
$ query-> bindParam (': пълно име', 'Arthur Pendragoon');
$ query-> bindParam (': потребителско име', 'knightofarcadia');
$ query-> execute ();

Горният блок код само замества пълното име на потребител, но ще забележите, че той е практически идентичен с кода за вмъкване. Ние обвързваме условен резултат, в този случай потребителското име и обвързваме резултат за настройка, в този пример новото пълно име.

Прост модел на релационна база данни на нормализирана връзка много към много - приблизително вида структура, която Доктрината ще изгради от дефиниция на ORM

Прост модел на релационна база данни на нормализирана връзка много към много - приблизително вида структура, която Доктрината ще изгради от дефиниция на ORM

07. Изтриване

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

механични моливи срещу дървени моливи за рисуване

$ query = $ conn-> подгответе ('ИЗТРИВАНЕ ОТ профили КЪДЕ' потребителско име '=
: потребителско име);
$ query-> bindParam (': потребителско име', 'knightofarcadia');
$ query-> execute ();

Горният SQL просто изтрива профил, където съвпадаме с потребителско име. Ние просто свързваме потребителското име с условната променлива.

08. Превключване на система за управление на база данни

Сега, при условие, че структурата на таблицата на базата данни е идентична и че не използваме нищо нестандартизирано в собствена SQL система, можем просто да променим името на източника си на данни да сочи от една СУБД - в нашия първоначален пример Microsoft SQL Server - към друг (IBM DB2, например). Целият код, който сме направили оттогава, ще работи - без да е необходимо да се променя SQL.

Ще започнем с нашия низ за връзка, изглеждащ така:

$ conn = нов PDO ('sqlsrv: server = localhost; database = yourdbname',
„потребителско име“,
„парола“);
$ conn = new PDO ('ibm: DRIVER = {IBM DB2 ODBC DRIVER}; DATABASE = yourd
bname; HOSTNAME = localhost; PORT = 56789; PROTOCOL = TCPIP; ',' потребителско име ',
„парола“);

Друг от ключовите потребители на PDO библиотеката е MediaWiki, приложението, което задвижва всички проекти на Фондация Уикипедия

Друг от ключовите потребители на PDO библиотеката е MediaWiki, приложението, което задвижва всички проекти на Фондация Уикипедия

09. Транзакции

Транзакцията, по отношение на базата данни, е мястото, където спестявате набор от заявки за групово обработване по-късно. PDO осигурява механизъм за изграждане на транзакции - но тъй като те силно зависят от системата за управление на базата данни, PDO транзакциите работят само когато се свързват към подмножество на RDBMS, което PDO поддържа. Ако се опитате да започнете транзакция на RDBMS, която не поддържа транзакции, ще получите доста гадна PDO транзакция. Така че нека анализираме някои кодове на транзакции:

опитвам {
$ conn-> beginTransaction ();
$ insertsql = $ conn-> подготви ('ВМЪКНЕТЕ В профили (потребителско име, пълно име,
роден град) СТОЙНОСТИ ('wilfred', 'Wilfred Jones', 'Scarborough') ');
$ deletesql = $ conn-> подготви ('ИЗТРИВАНЕ ОТ профили КЪДЕ потребителско име =
„потребителско име“));
$ conn-> exec ($ insertsql);
$ conn-> exec ($ deletesql);
$ conn-> commit ();
} catch (Изключение $ e) {
$ conn-> rollBack ();
// съобщение достъпно с: $ e-> getMessage ();
}

Първо започваме опит за улавяне, за да можем да уловим всички лоши изключения, включително тези, които може да получите, опитвайки се да се свържете със СУБД, която няма поддръжка на транзакции. Започваме транзакция с $ conn-> beginTransaction () преди да продължим да изграждаме нашите изпълнения на заявки, но те няма да бъдат напълно изпълнени в базата данни до $ conn-> commit () функцията се изпълнява и те ще се извършват в ефикасна последователна последователност - което означава, че можете да правите различни други PHP процеси между командите за изпълнение, без влияние върху базата данни.

Ако установим, че базата данни не поддържа транзакции, тогава транзакцията просто няма да се случи; ако бъде хвърлено друго изключение, тогава ние изпълняваме $ conn-> rollBack () , което ще отмени всички промени, направени от транзакцията. Заслужава да се отбележи, че когато се свързва с RDBMS, поддържан от транзакции, PDO ще влезе в състояние на „автоматично фиксиране“, където всяка команда exec сама по себе си е извършена транзакция; ако обаче искате да работите по безопасен начин, тогава винаги можете да използвате beginTransaction , и имат достъп до пакетното ангажиране и функционалността на връщането.

10. Проблеми с PDO

От гледна точка на PHP няма реални проблеми при използването на PDO. Той е обектно ориентиран, което означава, че е разтегателен и гъвкав и работи с много системи по свързващ начин. Проблемът възниква, когато смятаме, че докато по-голямата част от релационните системи за управление на бази данни следват стандартизацията на SQL (така че ни помага да превключваме от една система в друга), много системи имат свой собствен патентован синтаксис и функции, които не са често срещани за други системи.

Следователно е от решаващо значение за плавен преход от една система към друга да следвате стандартите на SQL и да използвате само често срещани функции. За пример това има функция, която често се използва в заявки: можем да разгледаме функцията за рандомизиране в SQL. Ето спецификациите на функциите за различни езици:

MySQL: SELECT RAND ([seed]);
MS SQL: ИЗБЕРЕТЕ РАНД ([семена]);
PostgreSQL: ИЗБЕРИ СЛУЧАЙНО (); (за да зададете семето, трябва да стартирате SETSEED ([seed])
предварително)
Oracle DB: SELECT dbms_random.random FROM dual;
SQLite: ИЗБЕРЕТЕ СЛУЧАЙНО ();

Така че трябва да имаме това предвид и да разберем дали можем да използваме стандартизирана SQL техника вместо собствената функция, или да използваме PHP процедура и да инжектираме резултата в SQL заявката (в примера за рандомизация можем да използваме ред () функция, която PHP предоставя).

Приложението gedit в Linux е един от най-бързите начини за модифициране на кода и има подчертаване на синтаксиса за много езици. Той използва системата Doctrine ORM

Приложението gedit в Linux е един от най-бързите начини за модифициране на кода и има подчертаване на синтаксиса за много езици. Той използва системата Doctrine ORM

11. Обектно релационно картографиране чрез пример

Разбира се, можем да стигнем по-далеч в абстракцията, като влезем в света на моделирането - не, не чрез излагане на нашия проект на моден подиум, а чрез картографиране на обикновени стари PHP обекти в таблици от бази данни. Има проблем с това, защото PHP обектите имат обектно-ориентиран модел, докато SQL базите данни имат релационен. Тук влиза в сила релационното картографиране на обекти (ORM): то ви позволява да картографирате обекти в таблици, често използвайки малко магия и малко блясък.

Вероятно питате каква е ползата от ORM. Съвсем просто, не е нужно да се занимавате с някоя от свързаността на базата данни или SQL заявки; просто използвате PHP обекти и техните методи директно, а системата ORM се занимава с цялата свързаност и транзакциите за създаване-четене-актуализиране-изтриване във фонов режим. Има доста ORM библиотеки за PHP, PdoMap , Задвижване и Червен боб като някои от добрите, но най-доброто, което съм използвал, е Учение 2 - има предимството да се използва самостоятелно или като част от настройка на MVC като Symfony, CodeIgniter или Zend.

С Doctrine 2 и няколко други ORM системи обикновено определяте набор от обекти и вида взаимоотношения, които те имат помежду си (като един към много; много към един; много към много) , със специални подробности за връзката между свойствата и методите. Разбира се, няма нужда да се дефинират нормализирани таблици на връзките, защото те не са от значение в обектния модел. Този изпълнен от човека процес обикновено се извършва с помощта на персонализиран синтаксис, например в XML или YAML, а Doctrine 2 дава възможност за релационни дефиниции на обекти в PHP doc-блокове. Следващият модел и код описва пример от реалния свят.

използвайте Doctrine Common Collections ArrayCollection;
/ ** Описание на члена
* @Entity
* /
член на класа {
/ **
* @Id @GeneratedValue
* @Column (type = 'integer')
* @не беше
* /
защитен $ id;
/ ** @ колона (тип = 'низ')
* @var низ
* /
защитено $ firstname;
/ ** @ колона (тип = 'низ')
* @var низ
* /
защитено фамилно име $;
/ ** @ колона (тип = 'низ')
* @var низ
* /
защитен имейл $;
/ ** Много членове имат членство в много групи
* @ManyToMany (targetEntity = 'Група')
* @var Group []
** /
защитени $ групи;
/ **
* Строител
* /
публична функция __construct () {
$ this-> groups = new ArrayCollection ();
// ...
}
// --- Примери за основен гетер и сетер --- //
/ ** Получава (вътрешния) идентификатор на члена
* @return int
* /
публична функция getId () {
върнете $ this-> id;
}
/ ** Получава собственото име на члена
* @ върнете низ
* /
публична функция getFirstname () {
върнете $ this-> firstname;
}
/ ** Задава собственото име на члена
* @param низ $ firstname
* /
публична функция setFirstname ($ firstname) {
$ this-> firstname = $ firstname;
}
// --- По-сложни примери за получаване и задаване --- //
/ ** Получава масива от групи на члена
* @return Group []
* /
публична функция getGroups () {
върнете $ this-> групи;
}
/ ** Присвоява група на член
* @param Group $ group
* /
публична функция assignToGroup (Group $ group) {
$ this-> groups [] = $ group;
}
/ ** Премахва член от група
* @param Group $ group
* /
публична функция removeFromGroups (Group $ group) {
$ this-> getGroups () -> removeElement ($ група);
}
// ...
}
?>

След това машинно изпълнен процес може да генерира SQL за създаване на база данни (това може да бъде в различни синтаксиси на SQL, като например MySQL, SQL Server или PostgreSQL); той може да направи това чрез изхвърляне на SQL или като се свърже с базата данни и я изпълни сам. Той сам ще създаде таблици с връзки много към много.

doctrine orm: schema-tool: create

или

доктрина орм: инструмент-схема: създай --dump-sql

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

$ група = нова група ();
// задаване на подробности за групата, персистиране и промиване (както по-долу)
$ member = нов член ();
$ member-> setFirstname ('');
$ member-> setSurname ('');
$ member-> setEmail ('');
$ member-> assignToGroup ($ група);
$ entityManager-> упорства ($ член);
$ entityManager-> flush ();
echo 'Създаден член с ID'. $ member-> getId (). 'н';

Разбира се, има и нещо повече от горните примери по-горе, най-вече по отношение на подробностите за връзката и зареждането, но мислех, че трябва да ви дам вкус на силата на ORM и по-специално на доктрината. Трябва да добавя, че Doctrine 2 и няколко други PHP ORM библиотеки използват PDO, за да постигнат поддръжка за различни различни RDBMS.

линия, начертана за показване на изразително движение.

Полезно, системата Доктрина включва обширна вградена помощ, когато имате нужда от нея

Полезно, системата Доктрина включва обширна вградена помощ, когато имате нужда от нея

12. Заключение

Използвал съм PDO в търговски проекти и от моя собствен опит той значително увеличава лекотата на свързване с база данни - и справяне с данните след това - благодарение на обектната си ориентация. Няма нужда да се използва PDO само за възможността за превключване на системата; функциите са там, за да ги използвате, имат добра ефективност и са идеални за съвременни модели на дизайн на програмиране.

Има много системи, които все още използват специфични за процедурата функции, но със сигурност съм видял промяна на фокуса към PDO. Също така можем да видим PDO в действие в дивата природа, защото Drupal, MediaWiki, WordPress и много други популярни уеб приложения с отворен код сега напълно или частично поддържат PDO системата за свързване към бази данни. Имам визия, при която данните вече не са тясно свързани с бази данни и базите данни вече не са тясно свързани с код и виждаме, че по-общи системи с общо предназначение са конфигурирани за конкретни приложения. Мисля, че ORM системите, NoSQL и свързаните данни са три неща, на които трябва да се обърне внимание в настоящето и в бъдещето. Убийствените характеристики на бъдещите уеб приложения, първо, ще имат основите на свързаността на данните, и второ, чрез ефективността на манипулирането на тези данни.

Открийте 101 CSS и Javascript уроци.

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