Русская документация PHP-CPP

Объявление функций

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

void example1();
void example2(Php::Parameters &params);
Php::Value example3();
Php::Value example4(Php::Parameters &params);

В представленных выше сигнатурах упомянуто два важных класса. Это Php::Value и Php::Parameters. Php::Value — достаточно мощный класс, который по сути является тем же что и обычная php переменная. На самом деле, Php::Value и есть обертка над структурой php переменной zval, но с дополнительными возможностями. Соответственно, в объетк типа Php::Value можно хранить то же что и в обычных php переменных — целые, строки, массивы, php-объекты и т.д. Класс Php::Parameters можно с равнить с массивом (или вектором) аргументов, переданных в функцию.

Что бы вашу C++ функцию можно было сделать вызываемой из PHP, вы должны добавить указатель на вашу функцию в объект ващего расширения и назначить ей имя, под которым эта функция будет известна в PHP.

Сказанное иллюстрирует следующий пример:

#include <phpcpp.h>
#include <iostream>

void myFunction()
{
    Php::out << "example output" << std::endl;
}

extern "C" {
    PHPCPP_EXPORT void *get_module() {
        static Php::Extension extension("my_extension", "1.0");
        extension.add("myFunction", myFunction);
        return extension;
    }
}

Не трудно понять, что делает приведенный выше код. Если вы установите расшиерение из приведенного выше примера, то в ваших php скриптах будет доступна функция myFunction() которая, при ее вызове, будет выводить

example output

Как мы уже ранее говорили, имеется четыре типа сигнатур функций, которые вы можете использовать. В первом примере мы проиллюстрировали один, самый простой, тип — который ничего не возвращает и не принимает ни каких аргументов. Что если вам нужна функция, возвращающая значения и принимающая аргументы?

#include <phpcpp.h>
#include <stdlib.h>

Php::Value myFunction()
{
    if (rand() % 2 == 0)
    {
        return "строка";
    }
    else
    {
        return 123;
    }
}

extern "C" {
    PHPCPP_EXPORT void *get_module() {
        static Php::Extension extension("my_extension", "1.0");
        extension.add("myFunction", myFunction);
        return extension;
    }
}

Здорово? В PHP совершенно невозбранно можно создать функцию которая в каких то случаях возвращает значения одного типа (например целое), в каких то другого (например строку). В C++ тип возвращаемого значения функции всегда один и тот же. Но, поскольку, Php::Value позволяет приведение к нему различных типов, мы можем создать C++ функцию возвращающую, как и в PHP, различные значения в различных ситуациях.

Вот пример использования нашей функции:

<?php
    for ($i=0; $i<3; $i++) echo(myFunction()."\n");
?>

Возможный вывод этого сценария будет:

123
123
строка

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

#include <phpcpp.h>

/*
 *  Функция принимает произвольное число аргументов (в PHP коде)
 *  и возвращает их сумму
 */
Php::Value sum_everything(Php::Parameters &parameters)
{
    int result = 0;
    for (auto &param : parameters) result += param;
    return result;
}

extern "C" {
    PHPCPP_EXPORT void *get_module() {
        static Php::Extension extension("my_extension", "1.0");
        extension.add("sum_everything", sum_everything);
        return extension;
    }
}
Это выглядит очень просто, вы не находите? Класс Php::Parameters является производным от std::vector. Поэтому мы смогли итерировать объект parameters.

Обратите внимание, как мы использовали оператор += с объектом param класса Php::Value. Мы прибавляли param к целому result а затем вернули result в качестве результата функции. И он автоматически был преобразован к Php::Value.

Функция sum_everything() теперь может быть доступна в ваших PHP скриптах (после установки расширения с ней). Давайте протестируем ее.

<?php
    echo sum_everything(10, "100", 20.5);
?>

Результат:

130

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

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

Установка PHP-CPP Загрузка расширений Ваше первое расширение Вывода и ошибок Функции Параметры Вызов функций и методов Классы и объекты Конструкторы и деструкторы Наследование Магические методы Магические интерфейсы Генерация исключений Специальные возможности Поля классов Работа с переменными ini записи Extension callbacks Пространства имен