Пример за REST API с PHP от нулата, без употреба на фреймуърк

Преди да започна с примера, ще се опитам с мой (прости) думи да обясня какво се има предвид под REST API и за какво в крайна сметка се използва.

Какво е REST API

REST съкратено от Representational State Transfer – стил софтуерна архитектура за реализация на уеб услуги. Най-общо, това е концепция за заделяне на системен ресурс, който се променя въз основа на взаимодействието между клиент и сървър. В общи линии клиентът прави заявка, сървърът я обработва и връща отговор, съответстващ на заявката. Архитектурният стил на REST прилага 6 условия и когато дадено приложение покрива тези условия, то може да се нарече RESTful.

API (съкратено от Application Programming Interface) е набор от правила, които позволяват на една част от софтуерна програма да комуникира с друга част. Повече подробности са достъпни в wikipedia.

RESTful API е уеб приложение, което базирано на принципите на REST и HTTP. Често се използва с медийния тип JSON, но работи и с останалите типове. Базовите операции, които поддържа, са GET, PUT, POST и DELETE.

За какво най-общо се използва REST API

Пример 1: REST API

Имаме онлайн бизнес и искаме да проверим посещенията за даден месец. Един от вариантите е да ползваме API функциите на Google Developers, чрез които ще получим достъп до данните в Google Analytics. По този начин няма да бъде необходимо всеки път да зареждаме цялото приложение на Google Analytics, а ще можем да следим това, което ни интересува от собственото табло (dashboard) на нашето приложение.

Пример 2: RESTful API

Например, работим с уеб базиран библиотечен софтуер за управляване и проследяване на библиотечни единици и читатели на библиотека. Приложението има база данни с пълно библиографско описание на книги, с които разполага библиотеката. Софтуерът е качен на lib.example.com. Чрез RESTful API архитектурата приложението може да предостави достъп до данните на уеб сайта на библиотеката и същевременно до уеб сайтовете на училищата.

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

Условие и реализиране на задачата

Да си представи че имаме следната задача – клиент прави заявка за извеждане на статистика с посетителите на собствения си уеб сайт. Тези данни се изтеглят от различна база данни/приложение. Резултатът, който би трябва да получи клиентът, е посетителите за даден месец.

Примерен отговор:

{„error“: false, „message“: „“, data: [„Google Analytics“ : 150, „Positive Guys“: 5000]}

Задължителни изисквания

  • Да поддържа няколко източника. Лесно да се добавят нови източници.
  • Трябва да може да се справя с голямо разнообрази от методи.
  • Да прехваща грешно въведени данни.
  • Да връща JSON формат.
  • Да не се използва фреймуърк.

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

Решение

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

За улеснение ще разделим проекта на две части, като в първата част ще разработим API приложението, а във втората – клиента.

Изграждане на база данни/приложение за получаване на статистиката

Създаваме API приложението в папка api_project и в нея създаваме index.php файл, в който ще се съдържа цялото приложение.

<?php
header("Content-Type:application/json");
if (!empty($_GET['month']))
{
    $numberOfMonth = $_GET['month'];
    $monthData = get_month($numberOfMonth);
    if (empty($monthData))
    {
        response(TRUE, "Out of Range", NULL);
    } else
    {
        response(FALSE, "", $monthData);
    }
} else
{
    response(400, "Invalid Request", NULL);
}
function response($status, $status_message, $data)
{
    header("HTTP/1.1 " . $status);
    $response['error'] = $status;
    $response['message'] = $status_message;
    $response['data'] = $data;
    $json_response = json_encode($response);
    echo $json_response;
}
function get_month($numberOfMonth)
{
    $monthlyStats = [
        "january" => ['Google Analytics' => 50, 'Positive Guys' => 500],
        "february" => ['Google Analytics' => 150, 'Positive Guys' => 5000],
    ];
    foreach ($monthlyStats as $mKey => $curentMonth)
    {
        if ($mKey == $numberOfMonth)
        {
            return $curentMonth;
            break;
        }
    }
}

След това е необходимо да създадем .htaccess файл в същата папка и да опишем правилата, по които да се ръководи.

Най-общо разрешаваме пренаписването и достъпването на index.php с променлива month.

RewriteEngine On    

RewriteRule ^([a-zA-Z_-]*)\.(html|json|xml)?$ index.php?month=$1 [NC,L]

Така завършва първа част от проекта, като в резултат на това вече е налична „базата данни/приложението“, от където клиентът ще достъпва информация за посетителите на уеб сайта.

Изграждане на клиентска част, в която ще се получават статистическите данни

Клиентската част ще създадем в папка api_client с файл index.php. Съдържанието на файла ще представлява html страница, която ще е с много семпъл интерфейс, чрез който клиентът ще прави рикуест месец и ще респонсва месечната статистика.


<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">

        <title></title>
    </head>
    <body>

        <h2>Monthly website statistics</h2>
        <form  action="" method="POST">
    
                <select name="month">
                    <option>Select Month</option>
                    <option value="january">January</option>
                    <option value="february">February</option>
                </select>
            </div>
            <button type="submit" name="submit">Submit</button>
        </form>
        <p>&nbsp;</p>
        <h3>
            <?php
            if (isset($_POST['submit']))
            {
                $name = $_POST['month'];
                $url = "http://localhost/api_project/?month=" . $name;
                $client = curl_init($url);
                curl_setopt($client, CURLOPT_RETURNTRANSFER, true);
                $response = curl_exec($client);
                $result = json_decode($response);
                if (!empty($result))
                {
                    echo $result->error;
                    echo $result->message;
                    foreach ($result->data as $key => $value)
                    {
                        echo $key . ': ' . $value . '<br>';
                    }
                }
            }
            ?>
        </h3>

    </body>
</html>

След като всичко е готово, можем да тестваме приложението директно през браузъра на http://localhost/api_client/ и от там през формата. Другият вариант  е през Postman, като направим рикуест на localhost/api_project?month=february.

screenshot postman
в случай когато подадем грешни данни

 

 

Ще отбележа, че в този пример не са приложени най-добри практики, защото целта е да се придобие обща представа за архитектурата REST API с PHP.

Кратък урок как да инсталираме Laravel и Composer

За да започнем да програмираме с „Laravel“ първо трябва да подготвим средата и да инсталираме „Composer“ на нашата машина.

Нещата с които трябва да се съобразим  преди да инсталираме Composer:

  • PHP >= 5.6.4
  • OpenSSL PHP Extension
  • PDO PHP Extension
  • Mbstring PHP Extension
  • Tokenizer PHP Extension
  • XML PHP Extension

След като всичко е ок, може да преминем към инсталацията на „Composer“.

През Windows се изтегля .exe файла стартира се и се следват стъпките.

През Линукс и по точно Ubuntu е малко по различно изпълняват се следните команди в реда в който са изписани:

php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('SHA384', 'composer-setup.php') === '669656bab3166a7aff8a7506b8cb2d1c292f042046c5a994c43155c0be6190fa0355160742ab2e1c88d40d5be660b410') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"

След това се инсталира Ларавел със следния код

composer global require "laravel/installer"

Създаваме Ларавел проект с име „blog“

composer create-project --prefer-dist laravel/laravel blog

Създаваме  „Laravel“ проект с име „blog“  в папка /var/www /html/blog, под „Windows“ директорията  ще е друга, ако ползвате xampp би трябвало да е в C:\xampp\htdocs\blog. За да проверите дали всичко е сработило както трябва през браузъра пробвайте да заредите следния адрес „localhost/blog/public/“  като резултат трябва да получите това:

Laravel поздравителна страница
първоначална страница на Laravel

При Ubuntu ако получите „HTTP ERROR 500“ и Вие точно като мен се решава много лесно с следващите 2 команди:

sudo chmod 755 -R laravel_blog
chmod -R o+w laravel_blog/storage

След като получите екрана от скрийншота от горе… дет се вика „Let the coding begin!“

Поеми контрол върху потребителските роли

Днешните функции, които ще разгледаме в някои от случаите може да са ни от много голяма полза. Например когато трябва да предоставим на клиент Администраторски права за WordPress панела  и същевременно да го държим на страна от други места които не трябва да пипа. Моят съвет е – пазете администраторските права само за себе си! В по голямата част от потребителите не им трябва пълен контрол. Следващата функция може да ни е от полза, когато искаме да премахнем излишни мета боксове (meta boxes) от таблото (dashboard) и да си го персонализираме по собствен начин.

Ще започнем с премахване на цяла страница от основното меню в Админ панела. Да приемем, че даден потребител или група потребители не трябва да имат достъп до раздел Разширения(Plugins)


function remove_menu_pages() {
    $user = wp_get_current_user();
    if ($user->nickname == 'pe6o') {

         remove_menu_page( 'plugins.php' );
    }
}
add_action('admin_menu', 'remove_menu_pages', 101);

Кратко обяснение към кода: ако логнатия потребител е pe6o премахни раздел плъгинс. 

Този код ще забрани, редактирането на файлове по темата и плъгините може да го интегрирате директно в конфигурационния файл на WordPress „wp_config.php“.


define( 'DISALLOW_FILE_EDIT', true );

Следващия пример е премахване на второстепенна страница (submenu)


 remove_submenu_page('themes.php', 'nav-menus.php');

Този код ще премахне От раздела „Външен вид“ (Appearance) раздел Менюта (Menus)

Повече за премахване на страниците може да прочетете на WordPress codex като потърсите remove_menu_page.

Премахване на мета боксове от главното табло на WordPress

Сега да видим как да премахваме елементи или по правилно мета боксове от таблото. Да предположим, че новините от WordPress няма да ни трябват. За всеки случай ще постна и за останалите боксове данните.

function cw_remove_dashboard_element() {
    
     remove_meta_box('dashboard_primary', 'dashboard', 'side');
//   remove_meta_box('dashboard_incoming_links', 'dashboard', 'normal');
//   remove_meta_box('dashboard_plugins', 'dashboard', 'normal');
//   remove_meta_box('dashboard_secondary', 'dashboard', 'normal');
//   remove_meta_box('dashboard_quick_press', 'dashboard', 'side');
//   remove_meta_box('dashboard_recent_drafts', 'dashboard', 'side');
//   remove_meta_box('dashboard_recent_comments', 'dashboard', 'normal');
//   remove_meta_box('dashboard_right_now', 'dashboard', 'normal');
//   remove_meta_box('dashboard_activity', 'dashboard', 'normal'); //since 3.8
}

add_action('admin_init', 'cw_remove_dashboard_element');

Лично аз тези дема ги разработвам като плъгини, но може и по други начини примерно в function.php файла. За сега това е от мен, надявам се да съм ви бил полезен. Ако засечете някакви грешки или просто искате да ме питате или пишете не се колебайте да го направите през контактната форма.

Създаване на „facebook open graph tags“ плъгин

Плъгинът който ще направим днес, ще допринася за адекватното изглеждане на споделените връзки от нашия сайт в facebook а именно това са Open Graph Tags. Чрез Open Graph протокола изрично казваме на facebook crawler как да визуализира споделената връзка за да изглежда по-добре. Плъгинът ще прави това за нас автоматично, като на всеки пост, продукт или страница ще взима нейното заглавие, вид, адрес, съдържание и изображение.

Facebook crawler 

Чрез плъгинът, който ще направим поемаме контрол върху facebook роботът, като му казваме как искаме да изглежда нашата връзка.  Без Open Graph таговете процедурата става доста по тежка, след споделяне на връзка от вашия сайт роботът сканира страницата ви и взима това което му хареса.

Подходящ размер изображения

Друго на което според мен е хубаво да се обърне внимание са изображенията за високи резолюции използвайте картинка с размери 1200 x 630 пиксела, за ниски  600 x 315 пиксела. Като минимален  е 200 x 200, под този размер дебъгера ще даде грешка и няма да ни се вижда изображението.

Писане на код

Преди да преминем към същинската част ще трябва да си направим основните неща, като да си направим директория в папка Plugins и самият плъгин, ако сте забравили как става може да си го припомните от статията Как да си направим WordPress Plugin.

Следваща стъпка е да копирате кода.

add_action('wp_head', 'cw_facebook_tags');

function cw_facebook_tags() {

    if (is_single() || is_page() || is_home()) {
        ?>
        <meta property="og:title" content="<?php the_title() ?>" />
        <meta property="og:site_name" content="<?php bloginfo('name') ?>" />
        <meta property="og:url" content="<?php the_permalink() ?>" />

        <meta property="og:description" content="<?php $post = get_post($post); $content = substr($post->post_content, 0, 300);
        echo htmlspecialchars($content, ENT_COMPAT, 'ISO-8859-1', true);
        ?>" />

        <meta property="og:type" content="<?php if (is_home() || is_page()) { echo 'website'; } else { echo 'article'; } ?>" />

        <?php if (has_post_thumbnail()) : $image = wp_get_attachment_image_src(get_post_thumbnail_id(), 'large'); ?>
            <meta property="og:image" content="<?php echo $image[0]; ?>"/> 
        <?php endif; ?>

        <?php
    }
}

Като цяло няма нищо особено в този код, проверяваме дали е единичен пост, страница или началната страница на нашия уебсайт. Интегрираме мета таговете като за всеки взимаме данните които са необходими.

В GitHub профила съм качил малко по-разширена версия на плъгина. При интерес може да го разгледате или изтеглите от тук. Чрез него ще можете да задавате собствени og:title и og:description.

wordpress plugin for meta tags
Така изглежда плъгина

Как да си направим WordPress plugin, който изписва „Hello World“

Създаване на плъгин файл.

Първото нещо което трябва да направим е да създадем нова директория в инсталационния пакет на WordPress (wp-content\plugins),  там се намират всички инсталирани добавки към нашия сайт. На този етап директорията ще я именуваме my-first-plugin, в нея ще създадем php файл който ще именуваме my-first-plugin.php. Изискванията за да видим нашата добавката при другите в админ панела е да добавим в php файла веднага след отварящия php таг следния код:

**
* Plugin Name: My First WordPress Plugin
* Plugin URI: https://codewan.com
* Description: This is my first plugin.
* Version: 1.0.0
* Author: Ivan Balkanov
* Author URI: https://codewan.com
* License: GPL2
*/

Този php код както става ясно е коментар, който е видим в Административната част  „Разширения“на WordPress и дава информация относно плъгина и неговия автор. Минимумът за да стане активен нашия плъгин е  само Plugin Name: с този един ред ние вече виждаме нашата добавка и евентуално можем да я включваме или изключваме макар и да няма никакви функции в нея.

Добавяне на функционалност

За да се придържаме към протокола сега ще напишем и първата ни функция, която ще изписва „Hello, World!!“ в хедъра на страницата ни.


add_action('wp_head', 'hello_world');



function hello_world(){
echo 'Hello, World!';
}



Накратко имаме функцията hello_world() която при извикване изписва „Hello, World!“, това вероятно всеки го знае. Другото по различно нещо е как я извикваме. С първия ред от кода буквално казваме закачи функцията hello_world() към хедъра на нашия WordPress сайт.