diff options
Diffstat (limited to 'apidoc.txt')
-rw-r--r-- | apidoc.txt | 492 |
1 files changed, 0 insertions, 492 deletions
diff --git a/apidoc.txt b/apidoc.txt deleted file mode 100644 index 34eac2896c..0000000000 --- a/apidoc.txt +++ /dev/null @@ -1,492 +0,0 @@ -PHP Version 3.0 API Documentation - -Table of Contents ------------------ - 1. Function Prototype - 2. Function Arguments - 3. Variable number of function arguments - 4. Using the function arguments - 5. Memory management in functions - 6. Setting variables in the symbol table - 7. Returning values from functions - 8. Returning 'complex' values from functions (arrays or objects) - 9. Using the resource list -10. Using the persistent resource table -11. Adding runtime configuration directives ------------------ - -1. Function Prototype - - All functions look like this: - - PHP_FUNCTION(foo) { - - } - - Even if your function doesn't take any arguments, this is how it is - called. - ------------------ - -2. Function Arguments - - Arguments are always of type pval. This type contains a union which - has the actual type of the argument. So, if your function takes two - arguments, you would do something like the following at the top of your - function: - - pval *arg1, *arg2; - if (ARG_COUNT(ht) != 2 || getParameters(ht,2,&arg1,&arg2)==FAILURE) { - WRONG_PARAM_COUNT; - } - - NOTE: Arguments can be passed either by value or by reference. In both - cases you will need to pass &(pval *) to getParameters. If you want to - check if the n'th parameter was sent to you by reference or not, you can - use the function, ParameterPassedByReference(ht,n). It will return either - 1 or 0. - - When you change any of the passed parameters, whether they are sent by - reference or by value, you can either start over with the parameter by - calling pval_destructor on it, or if it's an ARRAY you want to add to, - you can use functions similar to the ones in internal_functions.h which - manipulate return_value as an ARRAY. - - Also if you change a parameter to IS_STRING make sure you first assign - the new estrdup'ed string and the string length, and only later change the - type to IS_STRING. If you change the string of a parameter which already - IS_STRING or IS_ARRAY you should run pval_destructor on it first. - ------------------ - -3. Variable number of function arguments - - A function can take a variable number of arguments. If your function can - take either 2 or 3 arguments, use the following: - - 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; - } - ------------------- - -4. Using the function arguments - - The type of each argument is stored in the pval type field: - - - This type can be any of the following: - - IS_STRING String - IS_DOUBLE Double-precision floating point - IS_LONG Long - IS_ARRAY Array - - IS_EMPTY ?? - IS_USER_FUNCTION ?? - IS_INTERNAL_FUNCTION ?? (if some of these cannot be passed to a - function - delete) - IS_CLASS ?? - IS_OBJECT ?? - - If you get an argument of one type and would like to use it as another, - or if you just want to force the argument to be of a certain type, you - can use one of the following conversion functions: - - 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 - - These function all do in-place conversion. They do not return anything. - - The actual argument is stored in a union. - - For type IS_STRING, use arg1->value.str.val - IS_LONG arg1->value.lval - IS_DOUBLE arg1->value.dval - -------------------- - -5. Memory management in functions - - Any memory needed by a function should be allocated with either emalloc() - or estrdup(). These are memory handling abstraction functions that look - and smell like the normal malloc() and strdup() functions. Memory should - be freed with efree(). - - There are two kinds of memory in this program. Memory which is returned - to the parser in a variable and memory which you need for temporary - storage in your internal function. When you assign a string to a - variable which is returned to the parser you need to make sure you first - allocate the memory with either emalloc or estrdup. This memory - should NEVER be freed by you, unless you later, in the same function - overwrite your original assignment (this kind of programming practice is - not good though). - - For any temporary/permanent memory you need in your functions/library you - should use the three emalloc(), estrdup(), and efree() functions. They - behave EXACTLY like their counterpart functions. 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. One of the biggest - improvements in PHP 3.0 will hopefully be the memory management. - - If you compile with "-DDEBUG", PHP3 will print out a list of all - memory that was allocated using emalloc() and estrdup() but never - freed with efree() when it is done running the specified script. - -------------------- - -6. Setting variables in the symbol table - - A number of macros are available which make it easier to set a variable - in the symbol table: - - SET_VAR_STRING(name,value) ** - SET_VAR_DOUBLE(name,value) - SET_VAR_LONG(name,value) - - ** Be careful here. The value part must be malloc'ed manually because - the memory management code will try to free this pointer later. Do - not pass statically allocated memory into a SET_VAR_STRING - - Symbol tables in PHP 3.0 are implemented as hash tables. At any given time, - &symbol_table is a pointer to the 'main' symbol table, and active_symbol_table - points to the currently active symbol table (these may be identical like in - startup, or different, if you're inside a function). - - The following examples use 'active_symbol_table'. You should replace it with - &symbol_table if you specifically want to work with the 'main' symbol table. - Also, the same funcions may be applied to arrays, as explained below. - - * To check whether a variable named $foo already exists in a symbol table: - if (hash_exists(active_symbol_table,"foo",sizeof("foo"))) { exists... } - else { doesn't exist } - - * If you also need to get the type of the variable, you can use: - hash_find(active_symbol_table,"foo",sizeof("foo"),&pvalue); - check(pvalue.type); - - Arrays in PHP 3.0 are implemented using the same hashtables as symbol tables. - This means the two above functions can also be used to check variables - inside arrays. - - If you want to define a new array in a symbol table, you should do this: - - 1. Possibly check it exists and abort, using hash_exists() - or hash_find(). - 2. Code: - - pval arr; - - if (array_init(&arr) == FAILURE) { failed... }; - hash_update(active_symbol_table,"foo",sizeof("foo"),&arr,sizeof(pval),NULL); - - This code declares a new array, named $foo, in the active symbol table. - This array is empty. - - Here's how to add new entries to it: - - pval entry; - - entry.type = IS_LONG; - entry.value.lval = 5; - - hash_update(arr.value.ht,"bar",sizeof("bar"),&entry,sizeof(pval),NULL); /* defines $foo["bar"] = 5 */ - hash_index_update(arr.value.ht,7,&entry,sizeof(pval),NULL); /* defines $foo[7] = 5 */ - hash_next_index_insert(arr.value.ht,&entry,sizeof(pval),NULL); /* defines the next free place in $foo[], - * $foo[8], to be 5 (works like php2) - */ - - If you'd like to modify a value that you inserted to a hash, you must first retreive it from the hash. To - prevent that overhead, you can supply a pval ** to the hash add function, and it'll be updated with the - pval * address of the inserted element inside the hash. If that value is NULL (like in all of the - above examples) - that parameter is ignored. - - hash_next_index_insert() works more or less using the same logic - "$foo[] = bar;" works in PHP 2.0. - - If you are building an array to return from a function, you can initialize - the array just like above by doing: - - if (array_init(return_value) == FAILURE) { failed...; } - - and then adding values with the helper functions: - - 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)); - - Of course, if the adding isn't done right after the array - initialization, you'd probably have to look for the array first: - - pval *arr; - - if (hash_find(active_symbol_table,"foo",sizeof("foo"),(void **)&arr)==FAILURE) { can't find... } - else { use arr->value.ht... } - - Note that hash_find receives a pointer to a pval pointer, and - not a pval pointer. - - Just about any hash function returns SUCCESS or FAILURE (except for - hash_exists() that returns a boolean truth value). - -------------------- - -7. Returning 'simple' values from functions (integers, floats or strings) - - A number of macros are available to make it easier to return things from - functions: - - These set the return value and return from the function: - - 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) - - These only set the return value: - - 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) - - The string macros above will all estrdup() the passed 's' argument, - so you can safely free the argument after calling the macro, or - alternatively use statically allocated memory. - - If your function returns boolean success/error responses, always use - RETURN_TRUE and RETURN_FALSE respectively. - -------------------- - -8. Returning 'complex' values from functions (arrays or objects) - - Your function can also return a complex data type such as an object - or an array. - - Returning an object: - - 1. Call object_init(return_value). - 2. Fill it up with values: - - add_property_long(return_value,property_name,l) Add a property named 'property_name', of type long, equals to 'l' - add_property_double(return_value,property_name,d) Same, only a double - add_property_string(return_value,property_name,str) Same, only a string - add_property_stringl(return_value,property_name,str,l) Add a property named 'property_name', of type string, string is 'str' with length 'l' - - 3. Possibly, register functions for this object. In order to - obtain values from the object, the function would have to fetch - "this" from the active_symbol_table. Its type should be IS_OBJECT, - and it's basically a regular hash table (i.e., you can use regular - hash functions on .value.ht). The actual registration of the - function can be done using: - - add_method(return_value,function_name,function_ptr) - - - Returning an array: - - 1. Call array_init(return_value). - 2. Fill it up with values: - - add_assoc_long(return_value,key,l) add associative entry with key 'key' and long value 'l' - add_assoc_double(return_value,key,d) - add_assoc_string(return_value,key,str) - add_assoc_stringl(return_value,key,str,length) specify the string length - - add_index_long(return_value,index,l) add entry in index 'index' with long value 'l' - add_index_double(return_value,index,d) - add_index_string(return_value,index,str) - add_index_stringl(return_value,index,str,length) specify the string length - - add_next_index_long(return_value,l) add an array entry in the next free offset with long value 'l' - add_next_index_double(return_value,d) - add_next_index_string(return_value,str) - add_next_index_stringl(return_value,str,length) specify the string length - -------------------- - -9. Using the resource list - - PHP 3.0 has a standard way of dealing with various types of resources, - that replaces all of the local linked lists in PHP 2.0. - - Available functions: - - 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, and are used, for instance, for maintaining - file descriptors. - - Typical list code would look like this: - - 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; - - 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... - - 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). - -------------------- - -10. Using the persistent resource table - - PHP 3.0 has a standard way of storing persistent resources (i.e., - resources that are kept in between hits). The first module to use - this feature was the MySQL module, and mSQL followed it, so one can - get the general impression of how a persistent resource should be - used by reading mysql.c. The functions you should look at are: - php3_mysql_do_connect() - php3_mysql_connect() - php3_mysql_pconnect() - - The general idea of persistence modules is this: - 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. - - Shutting down persistent resources: - - When you register 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. - -------------------- - -11. Adding runtime configuration directives - -Many of the features of PHP3 can be configured at runtime. These -configuration directives can appear in either the designated php3.ini -file, or in the case of the Apache module version in the Apache .conf -files. The advantage of having them in the Apache .conf files is that -they can be configured on a per-directory basis. This means that one -directory may have a certain safemodeexecdir for example, while another -directory may have another. This configuration granularity is especially -handy when a server supports multiple virtual hosts. - -The steps required to add a new directive: - - 1. Add directive to php3_ini_structure struct in mod_php4.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_php4.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 |