Урок

Zephir и это руководство предназначены для разработчиков PHP, которые хотят создавать C-расширения с меньшей сложностью.

Мы предполагаем, что вы знакомы с одним или несколькими языками программирования. Мы проводим параллели с функциями в PHP, C, Javascript и других языках. Мы будем указывать на функции в Zephir, которые схожи с их аналогами в других языках, а также на функции, поведение которых не является похожим или даже является новым. Если вы знаете какой-либо из этих языков, вы будете отмечать эти сходства и различия более быстро.

В этом руководстве мы будем использовать стандартные команды терминала Linux. Если вы являетесь пользователем Windows, вам нужно заменить эти команды их аналогами.

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

Если вы успешно установили Zephir, вы должны быть в состоянии выполнить следующую команду в своей консоли:

zephir help

Если все в порядке, на вашем экране должна появиться следующая справка (или очень похожая):

 _____              __    _
/__  /  ___  ____  / /_  (_)____
  / /  / _ \/ __ \/ __ \/ / ___/
 / /__/  __/ /_/ / / / / / /
/____/\___/ .___/_/ /_/_/_/
         /_/

Zephir 0.12.2 by Andres Gutierrez and Serghei Iakovlev (4ab69bd9)

Usage:
  command [options] [arguments]

Options:
      --dumpversion  Print the version of the compiler and don't do anything else
  -h, --help         Print this help message
      --no-ansi      Disable ANSI output
  -V, --version      Print compiler version information and quit

Available commands:
  api        Generates a HTML API based on the classes exposed in the extension
  build      Generates/Compiles/Installs a Zephir extension
  clean      Cleans any object files created by the extension
  compile    Compile a Zephir extension
  fullclean  Cleans any object files created by the extension (including files generated by phpize)
  generate   Generates C code from the Zephir code without compiling it
  help       Displays help for a command
  init       Initializes a Zephir extension
  install    Installs the extension in the extension directory (may require root password)
  stubs      Generates stubs that can be used in a PHP IDE

If something went wrong, please return back to the installation page.

Каркас расширения

Первое, что нам нужно сделать, это сгенерировать скелет расширения. Это предоставит нашему расширению базовую структуру, которую мы должны начать работать. В нашем случае мы создадим расширение под названием utils:

zephir init utils

После этого в текущем рабочем каталоге создается каталог с именем “utils”:

utils/
   ext/
   utils/

Каталог ext/ (внутри utils) содержит код, который будет использоваться компилятором для создания расширения. Другой созданный каталог — utils, этот каталог имеет то же самое, что и наше расширение. Мы разместим код Zephir в этом каталоге.

Нам нужно изменить рабочий каталог на “utils”, чтобы начать компилировать наш код:

cd utils
ls
ext/ utils/ config.json

В листинге каталога также будет отображаться файл с именем config.json. Этот файл содержит параметры конфигурации, которые мы можем использовать для изменения поведения Zephir и/или этого расширения.

Добавление нашего первого класса

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

Как и во многих языках/инструментах, первое, что мы хотим сделать, это увидеть hello world, сгенерированный Zephir, и проверить, что все в порядке. Итак, наш первый класс будет называться Utils\Greeting и он содержит метод печати hello world!.

Код для этого класса должен быть помещен в utils/utils/greeting.zep:

namespace Utils;

class Greeting
{

    public static function say()
    {
        echo "hello world!";
    }

}

Теперь нам нужно сообщить Zephir, что наш проект должен быть скомпилирован и сгенерировано расширение:

zephir build

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

    ...
Extension installed!
Add extension=utils.so to your php.ini
Don't forget to restart your web server

На этом этапе вполне вероятно, что вам потребуется указать пароль root, чтобы установить расширение.

Наконец, расширение должно быть добавлено в php.ini для загрузки PHP. Это достигается добавлением директивы инициализации: extension=utils.so к нему.

Замечание: Вы так же можете запускать PHP передавая ему в качестве опции -d extension=utils.so. Однако это одноразовый «трюк», вам необходимо будет поступать так каждый раз, тестируя ваше расширение в терминале. Добавление директивы в php.ini будет гарантировать, что расширение загружается для каждого запроса.

Первоначальное тестирование

Теперь, когда расширение было добавлено в ваш php.ini, проверьте, правильно ли загружается расширение, выполнив следующее:

php -m
[PHP Modules]
Core
date
libxml
pcre
Reflection
session
SPL
standard
tokenizer
utils
xdebug
xml

Расширения utils должны быть частью вывода, указывающего, что расширение было загружено правильно. Теперь давайте посмотрим на наш hello world, непосредственно выполняемый PHP. Для этого вы можете создать простой PHP-файл, вызывающий статический метод, который мы только что создали:

<?php

echo Utils\Greeting::say(), "\n";

Поздравляем! У вас есть первое расширение, работающее с PHP.

Удобные класс

Метод Utils\Greeting::say был хорош, чтобы проверить, правильно ли сконфигурирована наша среда. А теперь давайте создадим еще несколько полезных классов.

Первый полезный класс, который мы добавим к этому расширению, предоставит пользователям средства фильтрации. Этот класс называется Utils\Filter, и его код должен быть помещен в utils/utils/filter.zep:

Основным скелетом этого класса является следующее:

namespace Utils;

class Filter
{

}

Класс содержит методы фильтрации, которые помогают пользователям фильтровать нежелательные символы из строк. Первый метод называется alpha, и его целью является отфильтровать только те символы, которые являются основными буквами ASCII. Для начала, мы просто пройдем через строковую печать каждого байта в стандартный вывод:

namespace Utils;

class Filter
{

    public function alpha(string str)
    {
        char ch;

        for ch in str {
            echo ch, "\n";
        }
    }
}

При вызове этого метода:

<?php

$f = new Utils\Filter();
$f->alpha("hello");

Вы увидите:

h
e
l
l
o

Проверка каждого символа в строке проста. Теперь мы можем просто создать другую строку с правильными отфильтрованными символами:

class Filter
{

    public function alpha(string str) -> string
    {
        char ch; string filtered = "";

        for ch in str {
            if (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') {
                let filtered .= ch;
            }
        }

        return filtered;
    }
}

Полный метод может быть проверен, как и прежде:

<?php

$f = new Utils\Filter();
echo $f->alpha("!he#02l3'121lo."); // выведет "hello"

В следующем скринкасте вы можете посмотреть, как создать расширение, объяснённое в этом уроке: <iframe src="//player.vimeo.com/video/84180223" width="500" height="313" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen mark="crwd-mark"></iframe>

Заключение

Это очень простой учебник, и, как вы можете видеть, легко начать создание расширений с помощью Zephir. Мы приглашаем вас продолжить чтение руководства, чтобы вы могли ознакомиться с дополнительными функциями, которые предлагает Zephir!