PHP: PHP 개발 - Manual
PHP  
downloads | documentation | faq | getting help | mailing lists | | php.net sites | links | my php.net 
search for in the  
<디버거 프로토콜(Debugger Protocl)사용자 함수를 부르기>
view the version of this page
Last updated: Wed, 29 Jan 2003

부록 D. PHP 개발

PHP 3에 함수 추가

함수 표본

모든 함수는 다음과 같다:
void php3_foo(INTERNAL_FUNCTION_PARAMETERS) {
     
}
비록 함수가 어떤 인수도 갖지 않더라도 함수라 칭한다.

함수 인자

인자는 언제나 pval타입이다. 이 타입은 인자의 실제타입(actual type)의 결합을 포함한다. 그래서, 당신의 함수가 2개의 인자를 가진다면 당신은 당신의 함수 맨위에서 따르는것처럼 해야 할 것이다:

예 D-1. 함수 인자 가져오기

pval *arg1, *arg2;
if (ARG_COUNT(ht) != 2 || getParameters(ht,2,&arg1,&arg2)==FAILURE) {
   WRONG_PARAM_COUNT;
}
노트 : 함수는 값이나 참조 둘중 하나로 인자를 넘길수 있다. 양쪽 경우다 당신은 &(pval *) 에서 getParameters로 통과하는게 필요할 것이다. 당신이 체크하겠다면 몇번째 인자가 당신에게 참조값이나 아닌것으로 보내지는지 안다면 함수에서 사용할수 있다. ParameterPassedByReference(ht,n). 그건 1이나 0 값을 반환한다.

당신은 넘겨온 인자의 어떤것을 변경할때 그들은 참조나 값에 의해 보낼지 아닐지 pval_destuctor 라 불리운 인자를 시작하거나, 만약 배열이라면 추가할때 함수 비숫하게 배열같은 반환값을 다루는 internal_functions.h내에서 사용할수 있다

이미 당신은 IS_STRING으로 인자를 바꾼다면 새로운 estrdup()였던 문자열, 문자열 길이, 가장 나중에 바꾼 IS_STRING의 타입을 먼저 할당하는 것을 확실히 해야 한다. 이미 존재하는 IS_STRING이나 IS_ARRAY같은 인자의 문자열을 바꾼다면 pval_destructor를 먼저 실행해야 할 것이다.

변수형 함수 표본

이 함수는 표본의 변수형 숫자 가질 수 있다. 당신의 함수가 2개나 3개의 인자를 가질수 있다면 다음과 같이 사용하라:

예 D-2. 변수형 함수 인자

pval *arg1, *arg2, *arg3;
int arg_count = ARG_COUNT(ht);

if (arg_count < 2 || arg_count > 3 ||
    getParameters(ht,arg_count,&arg1,&arg2,&arg3)==FAILURE) {
    WRONG_PARAM_COUNT;
}

함수 인자 사용하기

각 인자의 타입은 pval타입 필드로 저장된다. 이 타입은 다음중 어느것이든 사용할수 있다:

표 D-1. PHP 내부 타입들

IS_STRINGString
IS_DOUBLEDouble-precision floating point
IS_LONGLong integer
IS_ARRAYArray
IS_EMPTYNone
IS_USER_FUNCTION??
IS_INTERNAL_FUNCTION?? (if some of these cannot be passed to a function - delete)
IS_CLASS??
IS_OBJECT??

당신이 하나의 타입 인자 가지는 것과 다른 것처럼 사용하길 바라는 것 또는 단지 확실한 타입의 인자를 시행하길 원한다면, 당신은 전환함수들 중 하나를 쓸수 있다:
convert_to_long(arg1);
convert_to_double(arg1);
convert_to_string(arg1); 
convert_to_boolean_long(arg1); /* If the string is "" or "0" it becomes 0, 1 otherwise */
convert_string_to_number(arg1);  /* Converts string to either LONG or DOUBLE depending on string */

이들 함수는 모두 하나로 변환를 한다. 아무런 반환을 하지 않는다.

실제적인 인자는 결합체로 저장된다; 그 구성원은:

  • IS_STRING: arg1->value.str.val

  • IS_LONG: arg1->value.lval

  • IS_DOUBLE: arg1->value.dval

함수내 메모리 관리

모든 메모리는 emalloc()이나 estrdup()로 할당되는 함수가 필요하다. 이것들은 malloc()와 strdup()함수과 같이 보이는 메모리처리가상함수이다. 메모리는 efree()로 해제될수 있다.

이 프로그램내에서 두 종류의 메모리는: 변수형에서 파서를 반환하는 것과 당신이 내부 함수내 필요한 임시 기억장소. 당신이 문자열을 변수형으로 지정할때 반환된 파서가 emalloc()나 estrdup()에 먼저 메모리에 할당되었는지 확인해야 한다.

어떤 임시/ 영구 메모리를 위해 당신은 당신의 함수/라이브러리내에서 emalloc(), estrdup(), 그리고 efree() 함수 3개를 이용해야 한다. 당신은 사본 함수처럼 정확히 해야 할 것이다. Anything you emalloc() or estrdup() you have to efree() at some point or another, unless it's supposed to stick around until the end of the program; otherwise, there will be a memory leak. The meaning of "the functions behave exactly like their counterparts" is: if you efree() something which was not emalloc()'ed nor estrdup()'ed you might get a segmentation fault. So please take care and free all of your wasted memory.

만약 당신이 "-DDEBUG"로 컴파일한다면 PHP3는 지정된 emalloc()과 estrdup() 사용한 모든 메모리 리스트를 출력할 것이다. 명시된 스크립트가 실행되고 있을때는 efree()를 용한 해제를 해선 안된다.

심볼 테이블에서 변수형 설정

매크로들의 숫자는 심볼 테이블에서 더 쉽게 변수형으로 설정할 수 있다:

  • SET_VAR_STRING(name,value) [1]

  • SET_VAR_DOUBLE(name,value)

  • SET_VAR_LONG(name,value)

[1]

PHP 3.0의 심볼 테이블은 hash 테이블처럼 제공된다. 주어진 어떤 시간에 &symbol_table 은 'main' 심볼 테이블을 가르키고, active_symbol_table은 현재 실행중인 심볼 테이블을 가르킨다. (이것을은 아마 함수내에서 처음또는 다른때에도 동일할 것이다.)

다음은 'active_symbol_table'을 이용한 예제들이다. 당신이 명확하게 'main' 심볼 테이블로 작업하길 원하면 &symbol_table으로 그것을 대체해야 한다. 마찬가지로 같은 함수들도 배열도 아래에 밝힌 것처럼 적용될 것이다.

예 D-3. 심볼테이블내 $foo가 존재하는지 체크

if (hash_exists(active_symbol_table,"foo",sizeof("foo"))) { exists... }
else { doesn't exist }

예 D-4. 심볼테이블내 변수형의 크기 찾기

hash_find(active_symbol_table,"foo",sizeof("foo"),&pvalue);
check(pvalue.type);
PHP 3.0의 배열은 심볼 테이블처럼 같은 해시테이블로 사용하는 것을 제공된다. 두개 이상의 함수가 배열내에서 변수형을 체크하는 것을 할 수 있다는 뜻이다.

만약 당신 심볼테이블네에서 새로운 배열을 정의하길 원하면, 다음과 같이 해야 한다.

먼저 당신은 체크하길 원하는 것이 존재하는 지 승인이 취소되었는지 hash_exists()나 hash_find()로 확인해야 한다.

다음, 배열을 초기화한다:

예 D-5. 새 배열 초기화

pval arr;
  
if (array_init(&arr) == FAILURE) { failed... };
hash_update(active_symbol_table,"foo",sizeof("foo"),&arr,sizeof(pval),NULL);
이 코드는 활성화된 심볼 테이블내에서 $foo란 이름으로 새 배열로 선언되었다. 이 배열은 비어 있다.

여기는 새 엔트리의 추가하는 법이다:

예 D-6. 새 배열에 엔트리 추가

pval entry;
  
entry.type = IS_LONG;
entry.value.lval = 5;
  
/* defines $foo["bar"] = 5 */
hash_update(arr.value.ht,"bar",sizeof("bar"),&entry,sizeof(pval),NULL); 

/* defines $foo[7] = 5 */
hash_index_update(arr.value.ht,7,&entry,sizeof(pval),NULL); 

/* defines the next free place in $foo[],
 * $foo[8], to be 5 (works like php2)
 */
hash_next_index_insert(arr.value.ht,&entry,sizeof(pval),NULL);
만약 당신이 당신이 hash에 삽입한 값을 바꾸고 싶다면 당신은 먼저 hash에서 그것을 반환해와야 한다. To prevent that overhead, 당신은 pval ** 에서 hash 추가 함수에 공급할수 있고, 그건 hash안에서 추가된 요소의pval * 주소로 수정될 수 있다. 만약 그 값이 NULL (모든 예제가 아닌 것처럼)이면, 그 인자는 무시된다.

PHP 2.0에서 hash_next_index_insert() "$foo[] = bar;"같은 동일한 로직으로 사용되었다.

만약 함수로부터 반환을 위한 배열을 만든다면, 다음과 같이 배열을 초기화할수 있다:

if (array_init(return_value) == FAILURE) { failed...; }

..그리고 helper함수와 함께 값을 추가한다

add_next_index_long(return_value,long_value);
add_next_index_double(return_value,double_value);
add_next_index_string(return_value,estrdup(string_value));

물론, 배열초기화후 추가하지 않겠다면, 배열을 먼저 찾아야 한다:
pval *arr;
  
if (hash_find(active_symbol_table,"foo",sizeof("foo"),(void **)&arr)==FAILURE) { can't find... }
else { use arr->value.ht... }

hash_find는 포인터에서 pval포인터와 pval포인터 아니어도 받는다.

거의 모든 hash 함수는 SUCCESS나 FAILURE만 반환한다. (불린 표준값을 반환하는 hast_exists()는 제외한다).

간단한 값 반환

매크로의 숫자은 함수로부터 간단하게 리턴받는게 가능하다.

RETURN_* 매크로들 모두 반환값과 함수에서 반환되는 되는 것을 정한다. The RETURN_* macros all set the return value and return from the function:

  • RETURN

  • RETURN_FALSE

  • RETURN_TRUE

  • RETURN_LONG(l)

  • RETURN_STRING(s,dup) If dup is TRUE, duplicates the string

  • RETURN_STRINGL(s,l,dup) Return string (s) specifying length (l).

  • RETURN_DOUBLE(d)

RETVAL_* 매크로는 리턴값을 설정할 수 있으나, 반환은 되지 않는다.

  • RETVAL_FALSE

  • RETVAL_TRUE

  • RETVAL_LONG(l)

  • RETVAL_STRING(s,dup) If dup is TRUE, duplicates the string

  • RETVAL_STRINGL(s,l,dup) Return string (s) specifying length (l).

  • RETVAL_DOUBLE(d)

문자열 스트링은 's'인자가 통과된 모든 estrdup() 이상일 것이다. 그리고, 당신 안전하게 부른 매크로를 부른후 인자를 해제를 할 수 있거나, 부가적으로는 지정된 메모리를 정적으로 사용할 수 있다.

만약 반환된 당신의 함수가 참/거짓 불린 값을 반환하면, 각각 RETURN_TRUE와 RETURN_FALSE 언제나 사용한다.

완전한 값 반환

당신의 함수는 이미 객체나 배열의 완전한 데이타 타입을 리턴할 수 있다.

객체 반환:

  1. object_init(return_value)를 부른다.

  2. 값으로 채운다. 모든 함수는 아래로 출력되는 결과가 가능하다.

  3. 가능하다면 이 객체를 위한 함수는 등록시킨다. 객체로부터 값을 차례대로 포함하고, 함수는 activ_symbol_table로부터 "this"를 가지고 와야 할 것이다. 이들 타입은 IS_OBJECT이 아니면 안되고, 기본적으로 정규 해시 테이블이어야 한다 (예, 당신은 .value.ht처럼 정규 해시 함수를 사용할 수 있다) 함수의 실제 등록은 다음과 같이 할수 있다:
    add_method( return_value, function_name, function_ptr );

The functions used to populate an object are:

  • add_property_long( return_value, property_name, l ) - long타입, I와 동일한 'property_name'이라는 프로퍼티 추가

  • add_property_double( return_value, property_name, d ) - 몇개의 double타입만 추가

  • add_property_string( return_value, property_name, str ) - 몇개의 string타입만 추가

  • add_property_stringl( return_value, property_name, str, l ) - 몇개의 'l'길이의 스트링만 추가'

배열 반환:

  1. array_init 부르기(return_value).

  2. 값으로 채우기. 함수는 아래 목록의 사용을 가능하게 한다.

The functions used to populate an array are:

  • add_assoc_long(return_value,key,l) - 'ken'키와 'I'의 long으로 된 공동 엔트리

  • add_assoc_double(return_value,key,d)

  • add_assoc_string(return_value,key,str,duplicate)

  • add_assoc_stringl(return_value,key,str,length,duplicate) 스트링 길이 지정

  • add_index_long(return_value,index,l) - 엔트리의 'index' 인덱스에 'i'으로 된 long을 추가

  • add_index_double(return_value,index,d)

  • add_index_string(return_value,index,str)

  • add_index_stringl(return_value,index,str,length) - 문자열 길이 지정

  • add_next_index_long(return_value,l) - 배열 엔트리의 'ㅣ'으로 된 long을 다음 free offset에 추가

  • add_next_index_double(return_value,d)

  • add_next_index_string(return_value,str)

  • add_next_index_stringl(return_value,str,length) - 문자열 길이 지정

자원 목록 사용하기

PHP 3.0은 여러 자원의 가지 형태를 다루는 표준적인 방법을 가지고 있다. 이것은 PHP 2.0의 모든 지역적인 linked list를 대체한다

가능한 함수:

  • php3_list_insert(ptr, type) - returns the 'id' of the newly inserted resource

  • php3_list_delete(id) - delete the resource with the specified id

  • php3_list_find(id,*type) - returns the pointer of the resource with the specified id, updates 'type' to the resource's type

Typically, these functions are used for SQL drivers but they can be used for anything else; for instance, maintaining file descriptors.

Typical list code would look like this:

예 D-7. Adding a new resource

RESOURCE *resource;

/* ...allocate memory for resource and acquire resource... */
/* add a new resource to the list */
return_value->value.lval = php3_list_insert((void *) resource, LE_RESOURCE_TYPE);
return_value->type = IS_LONG;

예 D-8. Using an existing resource

pval *resource_id;
RESOURCE *resource;
int type;

convert_to_long(resource_id);
resource = php3_list_find(resource_id->value.lval, &type);
if (type != LE_RESOURCE_TYPE) {
	php3_error(E_WARNING,"resource index %d has the wrong type",resource_id->value.lval);
	RETURN_FALSE;
}
/* ...use resource... */

예 D-9. Deleting an existing resource

pval *resource_id;
RESOURCE *resource;
int type;

convert_to_long(resource_id);
php3_list_delete(resource_id->value.lval);
The resource types should be registered in php3_list.h, in enum list_entry_type. In addition, one should add shutdown code for any new resource type defined, in list.c's list_entry_destructor() (even if you don't have anything to do on shutdown, you must add an empty case).

Using the persistent resource table

PHP 3.0은 영구적인 자원(persistent resources; 예, 그동안의 히트수를 보관하는 자원)을 저장하는 표준적인 방법을 가지고 있다. 이 방법은 MySQL 모듈에서 처음사용되었고, mSQL도 이것을 따르고 있다. 따라서 persistent resource를 어떻게 사용하는가에 대해 알고 싶다면 우선 mysql.c를 읽어보도록하자. 주의해서 볼 함수들은 다은과 같다:

php3_mysql_do_connect
php3_mysql_connect()
php3_mysql_pconnect()

persistence 모듈의 일반적인 idea는 다음과 같다:

  1. Code all of your module to work with the regular resource list mentioned in section (9).

  2. Code extra connect functions that check if the resource already exists in the persistent resource list. If it does, register it as in the regular resource list as a pointer to the persistent resource list (because of 1., the rest of the code should work immediately). If it doesn't, then create it, add it to the persistent resource list AND add a pointer to it from the regular resource list, so all of the code would work since it's in the regular resource list, but on the next connect, the resource would be found in the persistent resource list and be used without having to recreate it. You should register these resources with a different type (e.g. LE_MYSQL_LINK for non-persistent link and LE_MYSQL_PLINK for a persistent link).

If you read mysql.c, you'll notice that except for the more complex connect function, nothing in the rest of the module has to be changed.

The very same interface exists for the regular resource list and the persistent resource list, only 'list' is replaced with 'plist':

  • php3_plist_insert(ptr, type) - returns the 'id' of the newly inserted resource

  • php3_plist_delete(id) - delete the resource with the specified id

  • php3_plist_find(id,*type) - returns the pointer of the resource with the specified id, updates 'type' to the resource's type

However, it's more than likely that these functions would prove to be useless for you when trying to implement a persistent module. Typically, one would want to use the fact that the persistent resource list is really a hash table. For instance, in the MySQL/mSQL modules, when there's a pconnect() call (persistent connect), the function builds a string out of the host/user/passwd that were passed to the function, and hashes the SQL link with this string as a key. The next time someone calls a pconnect() with the same host/user/passwd, the same key would be generated, and the function would find the SQL link in the persistent list.

Until further documented, you should look at mysql.c or msql.c to see how one should use the plist's hash table abilities.

One important thing to note: resources going into the persistent resource list must *NOT* be allocated with PHP's memory manager, i.e., they should NOT be created with emalloc(), estrdup(), etc. Rather, one should use the regular malloc(), strdup(), etc. The reason for this is simple - at the end of the request (end of the hit), every memory chunk that was allocated using PHP's memory manager is deleted. Since the persistent list isn't supposed to be erased at the end of a request, one mustn't use PHP's memory manager for allocating resources that go to it.

When you register a resource that's going to be in the persistent list, you should add destructors to it both in the non-persistent list and in the persistent list. The destructor in the non-persistent list destructor shouldn't do anything. The one in the persistent list destructor should properly free any resources obtained by that type (e.g. memory, SQL links, etc). Just like with the non-persistent resources, you *MUST* add destructors for every resource, even it requires no destructotion and the destructor would be empty. Remember, since emalloc() and friends aren't to be used in conjunction with the persistent list, you mustn't use efree() here either.

런타임 설정 지시자(directives) 추가

많은 PHP의 기능(feature)들이 실행중에 설정 가능하다. 이 설정 지시자(configuration directives)는 php3.ini에 설정되거나, Apache 모듈의 경우 .conf 파일에 설정가능하도록 되어 있다. Apache .conf 파일에 설정하는 것의 장점은 디렉토리별로 설정을 다르게 할 수 있다는 점이다. 이것은 예를들어 어떤 디렉토리가 다른 디렉토리를 가지고 있어도, 해당하는 한 디렉토리에만 safemodeexecdir 설정을 할 수 있다는 것이다. 이 개별 설정 기능은 서버가 multiple virtual hosts를 지원할 때 무척 유용하다

The steps required to add a new directive:

  1. Add directive to php3_ini_structure struct in mod_php3.h.

  2. In main.c, edit the php3_module_startup function and add the appropriate cfg_get_string() or cfg_get_long() call.

  3. Add the directive, restrictions and a comment to the php3_commands structure in mod_php3.c. Note the restrictions part. RSRC_CONF are directives that can only be present in the actual Apache .conf files. Any OR_OPTIONS directives can be present anywhere, include normal .htaccess files.

  4. In either php3take1handler() or php3flaghandler() add the appropriate entry for your directive.

  5. In the configuration section of the _php3_info() function in functions/info.c you need to add your new directive.

  6. And last, you of course have to use your new directive somewhere. It will be addressable as php3_ini.directive.



User Contributed Notes
PHP 개발
add a note add a note
chrisv at chrisv dot darkhaven dot net
09-Aug-1999 02:50

One thing i've noted is that hash_find() and hash_exists() don't work with php4.


if(hash_find(arr->value.ht, "key",
sizeof("key"), (void *)tmp) == SUCCESS) {

stuff...

} else {

 other stuff...

}



The code that is written using that won't load into PHP. Use _php3_hash_find() and _php3_hash_exists() instead:


if(_php3_hash_exists(arr->value.ht, "key", sizeof("key"), (void *)tmp) {

 stuff

} else {

 more stuff

}



It works with both, although the "(void *)" needs to be changed to "(void **) for php4.

befletch at yahoo dot com
30-Sep-1999 12:33

Something about the PHP build process is needed here; perhaps an example showing how to make your own "Hello, World" extension.  Since that doesn't exist yet...


If you want to create an extension, you will need reasonably current versions of the tools m4, autoconf, libtool, and (I think) automake.  All of these are available at .


Once these are installed, go into the 'ext' directory of your php install and run the 'ext_skel' script to create your extension directory with some skeleton contents.  You will need to edit at least the config.m4 file, and of course add your own code.  Other extensions are useful models, and the GNU documentation for autoconf is useful for understanding macros used in config.m4.


The final step required to insert your code into the PHP build process is to go to the php root directory and run the 'buildconf' script.  You should now find references to your extension in the 'configure' script, and if you designed your config.m4 to make your extension conditional, 'configure' should have command-line switches for you.


After running 'configure', your extension should now be part of PHP's build process.  (You may want to verify that php_config.h has properly set any 'HAVE_<your-extension-here>' macros properly defined.)  If this all goes well, you should be ready to concentrate on the C code for your extension.

quentin at uk dot research dot att dot com
17-May-2000 07:08

I couldn't find a simple description of how to build an extension to PHP, so after I'd worked it out, I wrote some instructions.  You can find them at





I hope someone finds them useful!

ale at tana dot it
14-Mar-2001 08:48

PORTING CUSTOM C FUNCTION FROM PHP3 TO PHP4

And I mean just functions, not full-fledged php extension. I had a couple
of them, working with PHP3, and I have ported them in PHP4. Here's how.

1) Makefile
you should have CFLAGS something like

-I/path/to/php/php-4.0.4pl1/Zend
-I/path/to/php/php-4.0.4pl1
-I/path/to/php/php-4.0.4pl1/TSRM
-I/path/to/php/php-4.0.4pl1/main
-fPIC
-DCOMPILE_DL=1

Only the include paths changed from PHP3.

2) Interface with PHP
the php3_module_entry is now called zend_module_entry and has
the same structure. The get-module function from which you used to
return that value is not DLEXPORT, but ZEND_DLEXPORT. You
may want to use the ZEND_GET_MODULE macro.

For the function_entry, you may want to use the PHP_FE macros,
but I found the PHP_NAMED_FUNCTION implied less changes.
It goes as
PHP_NAMED_FUNCTION(arrayret); /* declaration */
and

/* in php3 was
DLEXPORT void arrayret(INTERNAL_FUNCTION_PARAMETERS) */
PHP_NAMED_FUNCTION(arrayret) /* definition */
{
pval **arg;
char buf[512];
int ok = 0, i = -1;

if (ZEND_NUM_ARGS() != 1 ||
zend_get_parameters_ex(1, &arg) != SUCCESS ||
(*arg)->type != IS_STRING ||
(*arg)->value.str.val == NULL)
{
WRONG_PARAM_COUNT;
}
...
You've seen that *arg becomes **arg. The ..._ex() function will take
the address of a pointer to pointer. ZEND_NUM_ARGS doesn't take
any parameter (used to be ht).

3) Includes

#include <php.h>
#include <zend_globals.h>

4) Insert indirection
One difficult point is the extra level of indirection that was introduced
for reference counting. If you don't use complex data types your C
function should now work. If you use, e.g., arrays, keep that level
of indirection in mind: don't store a pval into an array, store a pointer.

I had things as

if (array_init(return_value) == SUCCESS)
{
   ok = 1;
   for (i = 0; i < 100 && ok; ++i) /* insert 100 arrays in return value */
   {
      pval entry;
       char buf[80];

       if ((ok = array_init(&entry) == SUCCESS) != 0)
       {
          static char const entry_1[] = "one";
           static char const entry_2[] = "two";

           pval e1, e2;

           e1.value.str.val = e2.value.str.val = NULL;
           e1.type = e2.type = IS_STRING;

          e1.value.str.len = sprintf(buf, "%3d/%010u", i, i);
         e1.value.str.val = estrndup(buf, e1.value.str.len);
           ok = e1.value.str.val != NULL &&
              _php3_hash_update(entry.value.ht, (char*)entry_1,
                  sizeof entry_1, &e1, sizeof e1, NULL) == SUCCESS;

          if (ok) /* continue assigning a second string, etc... */
...

This stuff compiles due to some compatibilty macro definitions, but
it doesn't work. The quickest way around is to insert an intermediate
function. To make the code above work in PHP4 i preceded it with
the following:

#undef _php3_hash_update
#define _php3_hash_update php4_hash_update_patch

static int php4_hash_update_patch(HashTable *ht,
   char *arKey, uint nKeyLength,
   void *pData, uint nDataSize, void **pDest)
{
 zval *tmp;
   int rtc;

   if (nDataSize != sizeof(zval)) /* check it was a pval */
       return FAILURE;

  ALLOC_ZVAL(tmp); /* you need zend_globals.h for this */
   *tmp = *(zval*)pData;
   tmp->is_ref = 0;
   tmp->refcount = 1;
   if ((rtc = zend_hash_update(ht,
       arKey, nKeyLength,
       (void*)&tmp, sizeof(zval*), pDest)) == FAILURE)
   {
       FREE_ZVAL(tmp);
   }
   return rtc;
}

Similar patches can be done for _php3_hash_next_index_insert,
etcetera. You got the idea.

I hope this may save some time to an occasional code porter,
keep in mind I'm not a zend (sic) guru, I just crashed my head
quite hardly before realizing what was going wrong.

And

5) good luck!

akimov at e-mail dot ru
26-Apr-2001 05:19

I recomended visit Zend API Documentation pages


[editor note: These docs also live in the PHP manual

 

Use those docs to Extend PHP 4]

sylbert at geodesiconline dot com
21-Jun-2002 01:18

Just found out that functions in php need to neccessarily be in lower case! However, using a function like testMe doesn't throw any errors during compile time .. its just shows up as an undeclared function when called from a script. Instead use something like test_me & it works just fine.
add a note add a note

<디버거 프로토콜(Debugger Protocl)사용자 함수를 부르기>
 Last updated: Wed, 29 Jan 2003
show source | credits | mirror sites 
Copyright © 2001-2003 The PHP Group
All rights reserved.
This mirror generously provided by: /
Last updated: Thu May 22 21:11:29 2003 CEST