Введение в Zephir

Zephir — это язык, который обращается к основным потребностям разработчика PHP, пытающегося писать и компилировать код, который может быть выполнен PHP. Он динамически/статически типизирован, некоторые его функции могут быть знакомы разработчикам PHP.

Название Zephir является сокращением слов Z(end) E(ngine)/PH(P)/I(nte)r(mediate). Хотя это говорит о том, что произношение должно быть зефир, создатели Zephir фактически произносят его zaefire.

Привет мир!

Каждый язык имеет свой собственный пример "Привет мир!". В Zephir, этот вводный пример демонстрирует некоторые важные особенности этого языка.

Код в Zephir должен быть помещены в классы. Этот язык предназначен для создания объектно-ориентированных библиотек/фреймворков, поэтому использование кода без класса за очень редкими исключениями не допускается. Кроме того, наличие пространства имён является обязательным требованием:

namespace Test;

/**
 * Это пример класса
 */
class Hello
{
    /**
     * Это пример метода
     */
    public function say()
    {
        echo "Привет мир!";
    }
}

После компиляции этого класса он создает следующий код, который прозрачно компилируется gcc/clang/vc++:

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_test.h"
#include "test.h"

#include "kernel/main.h"

/**
 * Это пример класса
 */
ZEPHIR_INIT_CLASS(Test_Hello) {
    ZEPHIR_REGISTER_CLASS(Test, Hello, hello, test_hello_method_entry, 0);
    return SUCCESS;
}

/**
 * Это пример метода
 */
PHP_METHOD(Test_Hello, say) {
    php_printf("%s", "Привет мир!");
}

На самом деле, не ожидается, что разработчик, который использует Zephir должен знать или даже понимать C, однако, если у вас есть опыт работы с компиляторами, PHP внутренностей или самого языка C, это обеспечит более чёткий сценарий разработчику при работе с Zephir.

Понимание Zephir

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

Следующий пример очень прост, он реализует класс и метод с небольшой программой, которая проверяет типы массива.

Рассмотрим код подробно, чтобы мы могли начать изучать синтаксис Zephir. В нескольких строках кода много деталей! Мы объясним общие идеи здесь:

namespace Test;

/**
 * MyTest (test/mytest.zep)
 */
class MyTest
{
    public function someMethod()
    {
        /* Переменные должны быть объявлены */
        var myArray;
        int i = 0, length;

        /* Создать массив */
        let myArray = ["hello", 0, 100.25, false, null];

        /* Подсчитать массив в переменную типа int */
        let length = count(myArray);

        /* Вывод типов переменных */
        while i < length {
            echo typeof myArray[i], "\n";
            let i++;
        }

        return myArray;
    }
}

В методе в первых строках ключевые слова var и int. Этот синтаксис используется для объявления переменной в локальной области. Каждая переменная, используемая в методе, должна быть объявлена с соответствующим типом. Эта декларация не является обязательным, это помогает компилятору сообщать вам о неверном вводе переменных или об использовании переменных из сферы их применения, который обычно заканчивается ошибки во время выполнения.

Динамические переменные объявляются с помощью ключевого слова var. Эти переменные могут быть назначены и переназначены для разных типов. С другой стороны, i и length — целочисленные статические типизированные переменные, которые могут иметь только значения этого типа во всем исполнении программы.

В отличие от PHP, вам не нужно ставить знак доллара ($) перед именами переменных.

Zephir следует тем же соглашениям о комментариях, что и Java, C #, C ++ и т.д. Используя формат // комментарий, можно закомментировать строку, в то время как /* комментарий */ может быть использован для многострочных комментариев.

Переменные по умолчанию неизменяемы. На практике это означает, что Zephir ожидает, что большинство переменных остаются неизменными. Переменные, которые сохраняют свое первоначальное значение может быть оптимизированы компилятором до статических констант. Когда значение переменной должно быть изменено, должно быть использовано ключевое слово let:

/* Создать массив */
let myArray = ["hello", 0, 100.25, false, null];

По умолчанию, массивы являются динамическими, как в PHP, они могут содержать значения различных типов. Функции из PHP можно вызывать прямо в Zephir коде. В примере ниже, вызывается функция count. Но компилятор может выполняя оптимизацию избежать этого вызова, потому что он уже знает размер массива:

/* Подсчитать массив в переменную типа int */
let length = count(myArray);

Скобки в операторах управления потоком данных не являются обязательными. Хотя конечно, вы можете использовать их, если вам так больше нравится.

while i < length {
    echo typeof myArray[i], "\n";
    let i++;
}

PHP работает только с динамическими переменными, методы всегда возвращают динамические переменные. Это означает, что если возвращается статическая типизированная переменная, со стороны PHP вы получите динамическую переменную, которая может быть использована в PHP-коде. Обратите внимание, что память автоматически управляется компилятором. Это работает аналогичным образом, как и PHP, так что вам не нужно выделять или освобождать память как в C.