Phalcon PHP Framework Internal Documentation Release 1.0.0
Total Page:16
File Type:pdf, Size:1020Kb
Phalcon PHP Framework Internal Documentation Release 1.0.0 Phalcon Team Mar 15, 2017 Contents 1 Other formats 3 2 Table of Contents 5 2.1 General Considerations.........................................5 2.2 Phalcon API...............................................5 2.3 Common Structures...........................................6 2.4 Memory Management..........................................7 2.5 Variables.................................................8 2.6 Operations between Variables...................................... 11 2.7 Working with Arrays........................................... 12 2.8 Calling Functions............................................. 13 2.9 Objects Manipulation.......................................... 14 2.10 Calling Methods............................................. 16 2.11 Classes.................................................. 17 2.12 Throwing Exceptions........................................... 19 2.13 Compilation on Windows........................................ 19 2.14 License.................................................. 21 i ii Phalcon PHP Framework Internal Documentation, Release 1.0.0 Phalcon is not a traditional framework, it’s written as an C extension for PHP to provide high performance. The purpose of this document is to explain how it is built internally. If you’re interested in helping improve Phalcon, or simply understand how it works, this is the information you need. Contents 1 Phalcon PHP Framework Internal Documentation, Release 1.0.0 2 Contents CHAPTER 1 Other formats • PDF • HTML in one Zip • ePub 3 Phalcon PHP Framework Internal Documentation, Release 1.0.0 4 Chapter 1. Other formats CHAPTER 2 Table of Contents General Considerations Phalcon is a C extension for PHP developers. The way in which Phalcon is written is not the usual, if you compare the code of Phalcon with other C extensions you will see a considerable difference, this unusual way of write the extension has several objectives: • Provide a code that is closer to be understood by developers PHP • Create objects and components that act as close as possible to PHP objects • Avoid dealing with low-level issues, whenever possible • Help maintain a large base code like the Phalcon one When writing code for Phalcon try to follow these guidelines: • Writing the code in a PHP style, this will help to PHP developers to introspect easily understanding the internals of PHP objects. Reflection • Help the Phalcon user to obtain more human backtraces. • Don’t repeat yourself, if PHP has a functionality already developed, why do not simply use it? Phalcon API We the creators of Phalcon, are mainly PHP programmers, we are lazy and do not want to deal 100% of the time with low-level details like segmentation faults or memory leaks. We believe that PHP language is incredible, and Phalcon is a contribution to all those things we do every day and it could be faster. Moreover we want a fast and stable framework. For this reason, we have created the Phalcon API. The use of this API helps us to write C code in a PHP style. We have developed a number of functions to help the programmer to write code more interoperable with PHP in an easier way. 5 Phalcon PHP Framework Internal Documentation, Release 1.0.0 Phalcon API is based on the Zend API, but we have added more features to facilitate us the work. Phalcon is a very large project, frameworks need to be developed and improved every day, Phalcon API helps us write C code that is more stable and familiar to PHP developers. If you’re a PHP developer maybe you don’t know C or you don’t want to learn C, but after reading this guide you will find the Phalcon API very familiar to your knowledge. Common Structures To start explaining Phalcon, is necessary to understand a couple of low-level structures that are commonly used in the framework: Zvals Most variables used in the framework are Zvals. Each value within a PHP application is a zval. The Zvals are polymorphic structures, i.e. a zval can have any value (string, long, double, array, etc.). Inspecting some code you will see that most variables are declared Zvals. PHP has scalar data types (string, null, bool, long and double) and non-scalar data types (arrays and objects). There is a way to assign a value the zval according to the data type: PHALCON_INIT_VAR(name); ZVAL_STRING(name,"Sonny",1); PHALCON_INIT_VAR(number); ZVAL_LONG(number, 12000); PHALCON_INIT_VAR(price); ZVAL_DOUBLE(price, 15.50); PHALCON_INIT_VAR(nothing); ZVAL_NULL(nothing); PHALCON_INIT_VAR(is_alive); ZVAL_BOOL(is_alive, false); This is the internal structure of a zval: typedef union _zvalue_value { long lval; /* long value */ double dval; /* double value */ struct { char *val; int len; } str; HashTable *ht; /* hash table value */ zend_object_value obj; } zvalue_value; struct _zval_struct { /* Variable information */ zvalue_value value; /* value */ zend_uint refcount__gc; zend_uchar type; /* active type */ zend_uchar is_ref__gc; }; 6 Chapter 2. Table of Contents Phalcon PHP Framework Internal Documentation, Release 1.0.0 Most of the time you will not have to deal directly accessing the internal structure of a zval. Instead, the Zend API offers a comfortable syntax for altering its value or get information from it. Previously we saw how to change their values change according to the type, let’s see how to read their values: long number= Z_LVAL_P(number_var); char *str= Z_STRVAL_P(string_var); int bool_value= Z_BVAL_P(bool_var); If we want to know the data type of a zval: int type= Z_TYPE_P(some_variable); if (type== IS_STRING) { //Is string! } Zend Class Entries Another common structure we used is the zend class entry. Every class in the C internal world has its own zend class entry. That structure help us describe a class, its name, method, default properties, etc. //Get the class entry class_entry= Z_OBJCE_P(this_ptr); //Print the class name fprintf(stdout,"%s", class_entry->name); Memory Management As you may know, the memory management in C is all manual. Within a PHP extension, all memory is managed by Zend Memory Manager, however, the management remains manual. Manual memory management is a powerful tool that C offers. But, as PHP developers we are not used to this sort of thing. We like to just leave this task to the language without worrying about that. Phalcon MM To help in the creation of Phalcon, we have created the Phalcon Memory Manager (Phalcon MM) that basically tracks every variable allocated in order to free it before exit the active method: For example: PHP_METHOD(Phalcon_Some_Component, sayHello){ zval *greeting= NULL; //Add a memory frame PHALCON_MM_GROW(); PHALCON_INIT_VAR(greeting); ZVAL_STRING(greeting,"Hello!",1); 2.4. Memory Management 7 Phalcon PHP Framework Internal Documentation, Release 1.0.0 //Release all the allocated memory PHALCON_MM_RESTORE(); } PHALCON_MM_GROW starts a memory frame in the memory manager, then PHALCON_INIT_VAR allocates memory for the variable greeting, before exit the method we call PHALCON_MM_RESTORE, this releases all the memory allocated from the last call to PHALCON_MM_GROW. By this way, we can be sure that all the memory allocated will be freed, avoiding memory leaks. Let’s pretend that we used 10-15 variables, releasing manually the memory of them can be tedious. Others Kinds of Allocations PHALCON_INIT_VAR only allocates memory for zvals, if we want to request memory for other structures then we must use the functions that provides the Zend API. One very important thing to know is that an extension in C must never use the standard functions malloc and free. The Zend API has its own functions that make the memory access safer. char *some_word=( char *) emalloc(sizeof(char *) * 6); memcpy(some_word,"Hello",5); some_word[5]=0; efree(some_word); In short, emalloc allocates memory and efree frees it. If you forgot to make the efree you will get a memory leak. Variables Creation Unlike PHP, each variable in C must be declared at the beginning of the function in which we are working. Also, as noted above, all variables must be initialized before the use. Even, it should be reset again when we change its value, for example: //Declare the variable zval *some_number= NULL; //Initialize the variable and assign it a string value PHALCON_INIT_VAR(some_number); ZVAL_STRING(some_number,"one hundred",1); //Reinitialize the variable and change its value to long PHALCON_INIT_NVAR(some_number); ZVAL_LONG(some_number, 100); If a variable is assigned within a cycle or it’s re-assigned is important to initialize it to NULL in its declaration. By doing this, PHALCON_INIT_NVAR will know if the variable needs memory or it already have memory allocated. Copy-on-Write All the zval variables that we use in Phalcon are pointers. Each pointer points to its value in memory. Two pointers may eventually point to the same value in memory: 8 Chapter 2. Table of Contents Phalcon PHP Framework Internal Documentation, Release 1.0.0 zval *a= NULL, *b= NULL; PHALCON_INIT_VAR(a); ZVAL_LONG(a, 1500); b= a; //Print both zvals print the same value zend_print_zval(a,1); // 1500 zend_print_zval(b,1); // 1500 Changing the value of any of the two variables will change both pointers because their value are the same: ZVAL_LONG(b,-10); //Print both zvals print the same value zend_print_zval(a,1); // -10 zend_print_zval(b,1); // -10 Now, imagine the following PHP code: <?php $a= 1500; $b= $a; echo $a, $b; // 1500 1500 This is practically the same as we did before, however, let’s change the value of $b: <?php $a= 1500; $b= $a; echo $a, $b; // 1500