Наследование

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

Библиотека PHP-CPP также позволяет вам определять интерфейсы PHP и создавать иерархии классов PHP и PHP-интерфейсов.

Определение интерфейсов

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

/**
 *  Переключиться на C-контекст, чтобы гарантировать, что функция get_module ()
 *  может быть вызвана программами C (для которых движок Zend)
 */
extern "C" {
    /**
     *  Функция запуска, вызываемая движком Zend 
     *  для получения всей информации о расширении
     *  @return void*
     */
    PHPCPP_EXPORT void *get_module() {
        // создать статический экземпляр объекта расширения
        static Php::Extension myExtension("my_extension", "1.0");

        // описание интерфейса, чтобы PHP знал, какие методы
        // определены им
        Php::Interface interface("MyInterface");

        // определить метод интерфейса
        interface.method("myMethod", { 
            Php::ByVal("value", Php::Type::String, true) 
        });

        // регистрировать другие методы
        ...

        // добавить интерфейс к расширению
        // (или переместить его в расширение, что происходит быстрее)
        myExtension.add(std::move(interface));

        // вернуть расширение
        return myExtension;
    }
}

Получение и внедрение

Библиотека PHP-CPP пытается сделать работу с PHP и C ++ максимально прозрачной. Функции C ++ можно вызывать из сценариев пользовательского пространства PHP, а классы C ++ могут быть доступны из PHP. Тем не менее, в конце концов, PHP и C ++ все еще являются разными языками, а потому, что C ++ не имеет таких же функций отражения, как PHP, вам нужно будет указать механизм PHP, какие базовые классы и интерфейсы реализует класс.

Объект Php::Class имеет метод «extends()» и метод «implements()», который может использоваться для указания базовых классов и реализованных интерфейсов. Вам нужно пройти в классе или интерфейсе, который вы настроили ранее. Давайте посмотрим на пример.

/**
 *  Переключиться на C-контекст, чтобы гарантировать, что функция get_module () 
 *  может быть вызвана программами C (для которых движок Zend)
 */
extern "C" {
    /**
     *  Функция запуска, вызываемая движком Zend для получения
     *  всей информации о расширении
     *  @return void*
     */
    PHPCPP_EXPORT void *get_module() {
        // создать статический экземпляр объекта расширения
        static Php::Extension myExtension("my_extension", "1.0");

        // описание интерфейса, чтобы PHP знал, какие методы 
        // are defined by it
        Php::Interface myInterface("MyInterface");

        // определить метод интерфейса
        myInterface.method("myMethod", { 
            Php::ByVal("value", Php::Type::String, true) 
        });

        // зарегистрировать наш собственный класс
        Php::Class<MyClass> myClass("MyClass");

        // из скриптов пользовательского пространства PHP, он должен выглядеть так, как myClass реализует
        // интерфейс MyInterface
        myClass.implements(myInterface);

        // для интерфейса требуется, чтобы был реализован метод myMethod
        myClass.method<&MyClass::myMethod>("myMethod", {
            Php::ByVal("value", Php::Type::String, true) 
        });

        // создать третий класс
        Php::Class<DerivedClass> derivedClass("DerivedClass");

        // в PHP-скриптах, он должен выглядеть так, как у DerivedClass есть «MyClass»
        // в качестве основы
        derivedClass.extends(myClass);

        // добавить интерфейс и классы в расширение
        myExtension.add(myInterface);
        myExtension.add(myClass);
        myExtension.add(derivedClass);

        // return the extension
        return myExtension;
    }
}

Имейте в виду, что иерархия классов PHP, которую вы определяете внутри функции get_module (), не должна соответствовать иерархии классов C ++. Ваш класс C ++ «DerivedClass» вообще не должен иметь «MyClass» в качестве своей базы, хотя в PHP-скриптах он будет выглядеть так, как есть. Для удобства обслуживания кода, конечно, лучше сделать подпись PHP более или менее похожей на реализацию на C ++.

Далее.