C + + [kapalı] PHP uzantısı sarıcı

2 Cevap php

Ancak ben PHP C + + için bir sarıcı sınıf oluşturmak gerekir, PHP için yazma uzantısı bu alanda yeni duyuyorum. Şu anda PHP 5.2.13 kullanıyorum. Ben bu makaleyi http://devzone.zend.com/article/4486-Wrapping-C-Classes-in-a-PHP-Extension, ben linux sistemi için yazılır ancak PHP Zend ile iletişim kurmak için C + + sınıfı sarmak için devam nasıl bir öğretici okuyun. Siz PHP ile iletişim kurmak için bir sarıcı sınıf yazmak için devam nasıl herhangi bir madde veya tavsiye var mı?

2 Cevap

Bu benim son zamanlarda yapıyor oldum tam olarak ne olduğunu. Eğer başvurulan öğretici iyi bir (o da benim başlangıç ​​noktası idi) 'dir. İşte benim sınıfları sarılması için takip ettik temel süreç. Eğer C + + sınıfı adında sarma söylüyorlar Myclass:

Create php_myclass.h:

#ifndef PHP_MYCLASS_H
#define PHP_MYCLASS_H

extern "C" {
#include "php.h"
}

// Include your C++ class definition
#include "Myclass.h"

// Here is the struct which will represent the PHP version of your Myclass.
// It simply includes a pointer to a Myclass and a zend_object for PHP to 
struct myclass_object {
    zend_object std;
    Myclass *myclass;
};

// Here is whatever your PHP class is going to be called in the userspace (the PHP code)
#define PHP_MYCLASS_CLASSNAME "Myclass"
extern zend_class_entry *myclass_ce;
extern zend_object_handlers myclass_object_handlers;
zend_object_value myclass_create_handler(zend_class_entry *type TSRMLS_DC);

// Later, this will be the array full of your Myclass's method declarations
extern function_entry php_myclass_functions[];

#endif /* PHP_MYCLASS_H */

Sonra da php sınıfını tanımlamak php_myclass.cpp:

#include "php_myclass.h"

zend_class_entry *myclass_ce;
zend_object_handlers myclass_object_handlers;

// I'm still a newb, but I think this is the function that handles memory management when
// the PHP class is deleted (goes out of scope, script ends, whatever)
void myclass_free_storage(void *object TSRMLS_DC) 
{
    myclass_object *obj = (myclass_object*)object;
    delete obj->myclass;

    zend_hash_destroy(obj->std.properties);
    FREE_HASHTABLE(obj->std.properties);

    efree(obj);
}

// And likewise I believe this handles, as the name implies, mem management
// when your Myclass is instantiated.
zend_object_value myclass_create_handler(zend_class_entry *type TSRMLS_DC) 
{
    zval *tmp;
    zend_object_value retval;

    // make room in memory for a new PHP Myclass object:
    myclass_object *obj = (myclass_object*)emalloc(sizeof(myclass_object));
    // fill that memory with 0s
    memset(obj, 0, sizeof(myclass_object));
    obj->std.ce = type;

    // some magic stuff (no idea)
    ALLOC_HASHTABLE(obj->std.properties);
    zend_hash_init(obj->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
    zend_hash_copy(obj->std.properties, &type->default_properties, (copy_ctor_func_t)zval_add_ref, (void*)&tmp, sizeof(zval*));

    // make it so you can get an instance of this object in later code
    retval.handle = zend_objects_store_put(obj, NULL, myclass_free_storage, NULL TSRMLS_CC);
    retval.handlers = &myclass_object_handlers;

    return retval;
}

// First, we define some argument info for methods that take arguments (if we have any)
// This one means, obviously, one argument:
ZEND_BEGIN_ARG_INFO_EX(php_myclass_one_arg, 0, 0, 1)
ZEND_END_ARG_INFO()

// This one two args, etc.
ZEND_BEGIN_ARG_INFO_EX(php_myclass_two_args, 0, 0, 2)
ZEND_END_ARG_INFO()

// Here's where you tell PHP what methods your Myclass PHP class has.

function_entry php_myclass_functions[] = {
    // A special property at the end of this line for the constructor:
    PHP_ME(Myclass,__construct,NULL,ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)

    // Normal methods look like this:
    PHP_ME(Myclass,methodNameNoArgs,NULL,ZEND_ACC_PUBLIC)
    PHP_ME(Myclass,methodName1Arg,php_myclass_one_arg,ZEND_ACC_PUBLIC) 
    PHP_ME(Myclass,methodName2Args,php_myclass_two_args,ZEND_ACC_PUBLIC) 

    // Three magic NULL values, no idea why they have to go here.
    { NULL, NULL, NULL }
};

// And now, define each of those Myclass methods you just instructed PHP
// to expose to the userspace:
PHP_METHOD(Myclass, __construct)
{
    Myclass *myclass = NULL;
    zval *object = getThis();

    // Create an instance of the class you're wrapping
    myclass = new Myclass();

    // Make object (which points to $this for your PHP object instance)
    // an instance of the struct that represents your php class
    myclass_object *obj = (myclass_object*)zend_object_store_get_object(object TSRMLS_CC);

    // Set the internal Myclass of this to the instance of Myclass you just made
    obj->myclass = myclass;

    // Done.
}

PHP_METHOD(Myclass, methodNameNoArgs)
{
    // Get the current instance of your PHP Myclass into myclass:
    Myclass *myclass;
    myclass_object *mo = (myclass_object*)zend_object_store_get_object(getThis() TSRMLS_CC);\
    myclass = mo->myclass;

    if (obj == NULL) {
        // error checking
        RETURN_NULL();
    }

    // Return the value of your myclass method using one of the RETURN_* macros
    // Here we'll pretend this one returns boolean:
    RETURN_BOOL(myclass->methodNameNoArgs());
}

PHP_METHOD(Myclass, methodName1Arg)
{
    // Now, let's pretend your Myclass::methodName1Arg(int) takes an int
    // and returns a std::vector (which you want to be an array)
    long param;

    // Get the current instance of your PHP Myclass into myclass:
    Myclass *myclass;
    myclass_object *mo = (myclass_object*)zend_object_store_get_object(getThis() TSRMLS_CC);\
    myclass = mo->myclass;

    if (obj == NULL) {
        // error checking
        RETURN_NULL();
    }

    // Here's how you parse parameters of your PHP method call.
    // The second parameter is "l" for long int. Read the tutorials online for more
    // on how to use this function.
    if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", ¶m) == FAILURE) {
        RETURN_NULL();
    }

    // Get the real return value you want to translate for PHP
    std::vector retval = myclass->methodName1Arg(param);

    // Use the magic "return_value" (which is in every method behind-the-scenes)
    // and initialize it to be a PHP array:
    array_init(return_value);

    // Loop through the vector and build the array:
    for (std::vector::iterator i = retval.begin(); i != retval.end(); ++i) {
        add_next_index_long(return_value, *i);
    }

    // done. return_value is always returned for you.
}

PHP_METHOD(Myclass, methodName2Args)
{ 
    // "Left as an exercise for the reader" is coder slang for
    // "I *really* don't feel like typing anymore." :)
}

Ben bu örnek kod derler umut, ya da en azından yardımcı olur. :) Bu tür alelacele burada sahip gerçek çalışma kodu araya getirildi ve find / cümledeki şey kırdı eğer, en azından ne bir fikir alabilirsiniz. Bunun dışında kalan bol, http://devzone.zend.com/article/1021 daha Sara Golemon üç parçalı uzantıları öğretici okuyun. İyi şanslar.

Bulabileceğiniz en iyi "dokümantasyon" PHP kaynak kodu ve uzantıları (üzgünüm) 'dir. Size en kısa sürede size önemsiz olmayan bir şey yapıyoruz gibi kaynaklardan (Zend motorunun özellikle başlıkları) kazmak için var bulacaksınız.

Bunu söyledikten sonra, size başlamak için yararlı bulabileceğiniz birkaç kaynak vardır. these articles ve Extending and Embedding PHP by Sara Golemon bakın. Pecl.php.net / support.php Ayrıca bakınız