PHP и MySQL, 2. део

Знам да је нездраво висити на блогу и нон стоп постовати :), али боље да то урадим док је “свеже”. Надам се да ћете ми опростити ;).

Вечерас говоримо о раду са југо знацима латинице у MySQL бази података. Даћу вам пар савета како да свој живот учините једноставнијим и не проживљавате бол и патњу коју сам ја проживео :). Хвала богу па је кратко трајало. Ево пар савета:

1. у раду са MySQL базом, битно је да поставите collation на utf8_unicode_ci.
$dbh->query("ALTER DATABASE $database DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci");

2. после остваривања конекције са базом, из PHP-a, постављате сет карактера којим ћете моћи да вршите упите тј. које ће и PHP и MySQL разумети. Може се одредити на пар начина:
$baza = new PDO("mysql:host=$server;dbname=$db;charset=UTF-8", $user, $password);
или
$baza->exec('SET CHARACTER SET utf8');
или
$dbh->query('SET NAMES utf8'); (више објашњења овде);

На крају, када желите резултате представити на веб страни морате јој рећи како да тумачи ваше карактере. То се једноставно каже браузеру са:
<meta http-equiv="Content-Type" content="text/html charset=UTF-8" >
тагом који се постави унутар head html тага.

Advertisements

PHP и MySQL, 1. део

Поздрав свима, овим почињемо серије о PHP и MySQL, у виду неких трикова и трипова :).

Као што сам навео у последњем посту о JSON-у и PHP-у, у задње време радим са базом библиотеке факултета. Ишчитане податке приказујем помоћу jQuery-јевих DataTables. Примери које сам нашао и употребио у раду са базом су користили класичне mysql драјвере. У консултацији са асистентом, одлучили смо да користимо PDO драјвере. Пошто користим објектни PHP, PDO драјвери су логичан след ствари, јер омогућују да се резултатима упита аутоматски попуњавају објекти, који ће се инстанцирати на основу класе коју сами дефинишете. То је мени било врло интересантно, и на крају крајева био изазов. У преправкама кода, морао сам да преправљам и дефинисане MySQL упите. Ту долазимо до трипа и трика, који сам хтео да вам откријем.

У раду са DataTables, при позивању PHP скрипте која се налази на серверу, шаљу се параметри, међу којима и параметри о броју приказаних објеката, које добијете из упита. Тим параметрима се попуњава део упита, који изгледа овако:

"LIMIT ".mysql_real_escape_string( $_GET['iDisplayStart'] ).", ".mysql_real_escape_string( $_GET['iDisplayLength'] );

Искључимо функцију mysql_real_escape_string која припада класичним MySQL драјверима. Треба је заменити PDO еквивалентом, што представља мој следећи изазов. Овај део упита се комбинује са делом за сортирање и главним SELECT делом, и добија се упит који се изврши и врати тачно онолико објеката у табелу, колико је речено овим LIMIT упитом. Дакле, iDislpayStart говори бази од ког реда резултата узима податке, а iDisplayLength колико ће редова узети. Истовремено, је потребно вратити и податак о броју редова који је упит вратио, без LIMIT-а, наравно. То је трип, сложићете се. У почетку ми ово није било познато, тако да сам имао проблема. За параметре који се шаљу LIMIT наредби, користи се једна спуштајућа листа, са предефинисаним бројем резултата које желите да видите у табели (10,25,50,100). Колико год да сам изабрао, резултата је увек било, али исто онолико колико сам селектовао. То ми је било чудно, јер је резултата било више.

Део упита који сам намерно изоставио је био SQL_CALC_FOUND_ROWS, који иде одмах после SELECT наредбе. Незнајући сврху овога, јавили су се већ поменути проблеми. На крају сам на тежи начин научио чему ова наредба служи :). Наиме, коришћење овакве функције је много брже него извођење неког упита са LIMIT и без LIMIT наредбе. Она ће, при првом упиту израчунати број редова које упит врати, не рачунајући ограничења LIMIT-а. То је трик ;). Овим ћете једним ударцем (упитом), завршити два посла.

Упитом који следи, ћете покупити број објеката, које сте добили упитом. На овај начин, који је бржи, добијате број враћених података и лимитиране податке за испис у табели.

Ево sql упита:
SELECT FOUND_ROWS()
Надам се да ће неком бити од помоћи. Видимо се ускоро! 😉

JSON валидација и процесирање са сервера

У раду са базом података и подацима које је унео човек, увек ће се јавити проблеми. Једноставно је тако. То не можете избећи. Колико год ограничења да поставите, јавиће се проблем са неким податком, и то обично неки глупи проблем.

Од недавно сам почео да радим за подацима факултетске библиотеке. Подаци су били у access бази, па сам морао да их пребацим у mysql базу. Наравно, за то постоји релативно добар алат, на Убунту дистрибуцији Линукса. Зове се mdb-tools. Но, овде неће бити речи о томе. Реч је о JQuery-евим табелама (DataTables).

Ове табеле могу да се искористе за процесирање података са удаљеног сервера, и самим тим, вам задају главобољу :). Ок, можда сам једноставно таличан, па ви нећете имати проблема. Начин на који се прави табела и скрипта на серверу је описан овде. Оно што треба напоменути је да поред овог javascript кода, морате у html коду исписати костур табеле. Тај део није објашњен на линку, па ми је требало мало времена да укапирам шта је неопходно. PHP скрипта која вам враћа податке са сервера, враћа их у JSON облику. Заправо је врло битно да, уколико користите овај начин процесирања података од стране сервера, морате ускладити податке из табеле, јер се могу сукобити са правилима по којима JSON функционише.

Коначно долазимо до мог проблема, и једноставног решења :). У називу књига, јављају се знаци навода, што је у складу са правописом. Међутим, JSON на цео назив дода још по једне знаке на почетку и крају назива књиге. Урачунајте ту и људску глупост и ето вам главобоље док откријете где је проблем. Проблем се мора решити, или поновним уношењем свих књига 😉 (ко је кадар нек изволи), или неким sql query-јем, или као у мом случају: обрадом података које сам учитао из базе. Назив књиге можете трансформисати у низ, командом str_split, и онда проћи кроз низ и променити двоструке наводнике у једноструке. Ево мојег решења:

function quotations_fix(&$string1) {
    $niz_string1 = str_split($string1);
    foreach($niz_string1 as &$slovo) {
        if ($slovo == "\"") {
            $slovo = "'";
        }
        $string_fix .= $slovo;
    }
    $string1= $string_fix;
}

Функција се може реализовати и враћањем низа. Самим тим добијате мање кода, јер уместо враћања обичног назива књиге, можете да враћате резултат функције којој сте предали тај назив као аргумент.