


In-depth understanding of the member variables and methods of the PHP kernel (14) class, in-depth understanding of the kernel_PHP tutorial
In-depth understanding of the member variables and methods of the PHP kernel (14) class, and an in-depth understanding of the kernel
Original link: http://www.orlion.ga/1237/
The member variables of a class are essentially variables in PHP, but these variables all belong to a certain class, and there is access control for these variables.
The member method of a class is essentially a function in PHP, but this function exists as a class method. It may be a class method or an instance method, and class access control is added to these methods. The member methods of a class are abstractions of the behavior of real-world entities and can be used to implement the behavior of the class.
1. Member variables
Member variables have been registered in the class structure at compile time. The zend_do_begin_class_declaration function is called when the class declaration is compiled at compile time. This function is used to initialize the basic information of the class, including the member variables of the class. The calling sequence is [zend_do_begin_class_declaration]–>[zend_initialize_class_data]–>[zend_hash_init_ex]
zend_hash_init_ex(&ce->default_properties, 0, NULL, zval_ptr_dtor_func, persistent_hashes, 0);
Because the member variables of the class are stored in HashTable, the data is initialized using the zend_hash_init_ex function.
When declaring a class, the HashTable where the member variables of the class are located is initialized. If there is a new member variable attribute declaration later, zend_do_declare_property will be used at compile time. The function first checks some conditions that are not allowed in member variables:
-
Member variables are not allowed in interfaces
-
Member variables cannot have abstract properties
-
Cannot declare member variables as final
-
Attributes cannot be declared repeatedly
If a property is declared final in a class:
public final $var
Will report an error: Fatal error: Cannot declare property...This error is thrown by the zend_do_declare_property function:
if (access_type & ZEND_ACC_FINAL) { zend_error(E_COMPILE_ERROR, "Cannot declare property %s::$%s final, the final modifier is allowed only for methods and classes", CG(active_class_entry)->name, var_name- >u.constant.value.str.val); }
After the definition check is correct, the function will initialize the member variables.
ALLOC_ZVAL(property); // ¾ĘŴ if (value) { // ÒʻĻļUɩ ȐďĤ *property = value->u.constant; } else { INIT_PZVAL(property); Z_TYPE_P(property) = IS_NULL; }
During the initialization process, the program will first allocate memory. If this member variable has initialized data, the data will be assigned directly to the attribute. Otherwise, ZVAL will be initialized and its type will be set to IS_NULL. After the initialization process is completed, the program adds this member variable to the specified class structure by calling the zend_declare_property_ex function.
Regular member variables will eventually be registered in the default_propertiles field of the class. In our daily work, we may not use the processes mentioned above, but we may use the get_class_vars() function to view the member variables of the class. This function returns an associative array consisting of the default properties of the class. The elements of this array exist in the form of varname=>value. The core code for its implementation is as follows:
if (zend_lookup_class(class_name, class_name_len, &pce TSRMLS_CC) == FAILURE) { RETURN_FALSE; } else { array_init(return_value); zend_update_class_constants(*pce TSRMLS_CC); add_class_vars(*pce, &(*pce)->default_properties, return_value TSRMLS_CC); add_class_vars(*pce, CE_STATIC_MEMBERS(*pce), return_value TSRMLS_CC); }
First call the zend_lookup_class function to find the class named class_name and copy it to the pce variable. The core of this search process is a HashTable search function zend_hash_quick_find, which will search for EG (class_table). Determine whether the class exists and return it directly if it exists. If it does not exist, you need to determine whether it can be automatically loaded. If it can be automatically loaded, it will load the class and then return. If the class cannot be found, returns FALSE. If the class is found, initialize the returned array, update the class's static member variables, and add the class's member variables to the returned array. There is an update process for the static member variables of the class. We will introduce this process in the section about static variables below.
2. Static member variables
Static member variables of a class are common to all instances. They belong to this class, so they are also called class variables. In the PHP class structure, the static variables of the class itself exist in the default_static_memebers field of the class structure.
Unlike ordinary member variables, class variables can be called directly through the class name, which also reflects the specialness of being called a class variable. A PHP example:
class Tipi { public static $var = 10; } Tipi::$var;
View the intermediate code generated through the VLD extension:
function name: (null) number of ops: 6 compiled vars: !0 = $var line # * op fetch ext return operands ------------------------------------------------------------------------------- - - 2 0 > EXT_STMT 1 NOP 6 2 EXT_STMT 3 ZEND_FETCH_CLASS :1 'Tipi' 4 FETCH_R static member 'var' 5 > RETURN 1 branch: # 0; line: 2- 6; sop: 0; eop: 5 path #1: 0, Class Tipi: [no user functions]
This intermediate code only corresponds to the Tipi::$var call. It has little to do with the previous class definition. According to the content generated by VLD, we can know the PHP code: Tipi::$var, and the generated intermediate codes include ZEND_FETCH_CLASS and FETCH_R. This is just a call to a static variable, but it generates two intermediate codes. Reason: We want to call the static variables of a class. Of course, we must first find the class and then obtain the variables of this class. Judging from the PHP source code, this is because the zend_do_fetch_static_member function is called during compilation, and the zend_do_fetch_class function is called in this function, thus generating the ZEND_FETCH_CLASS intermediate code. Its corresponding execution function is ZEND_FETCH_CLASS_SPEC_CONST_HANDLER. This function calls the zend_fetch_class function (Zend/zend_execute_API.c). The zend_fetch_class function will eventually call the zend_lookup_class_ex function to find the class.
找到了类接着应该就是查找类的静态成员变量,其最终调用的函数为:zend_std_get_static_property。这里由于第二个参数的类型为ZEND_FETCH_STATIC_MEMBER。这个函数最后是从static_members字段中查找对应的值返回。而在查找前会和前面一样,执行zend_update_class_constant函数,从而更新此类的所有静态成员变量,静态变量更新流程图:
三、成员方法
成员方法从本质上来将也是一种函数,所以其存储结构也和常规函数一样,存储在zend_function结构体中。对于一个类的多个成员方法,它是以HashTable的数据结构存储了多个zend_function结构体。和前面的成员变量一样,在类声明时成员方法也通过调用zend_initalize_class_data方法,初始化了整个方法列表所在的HashTable。
除去访问控制关键字,一个成员方法和常规函数是一样的,从语法解析中调用的函数一样(都是zend_do_begin_function_declaration函数),但是其调用的参数有一些不同,第三个参数is_method,成员方法的赋值为1,表示它作为成员方法的属性。在这个函数中会有一系统的编译判断,比如在接口中不能声明私有的成员方法。
在此程序判断后,程序将方法直接添加到类结构的function_table字段,在此之后,又是若干的编译检测。比如接口的一些魔术方法不能设置为非公有,不能被设置为static,如__call()、__callStatic()、__get()等。
与成员变量一样,成员方法也有一个返回所有成员方法的函数–get_class_methods()。此函数返回由指定的类中定义的方法名所组成的数组。
四、静态成员方法
类的静态成员方法通常也叫做类方法。与静态成员变量不同,静态成员方法与成员方法都存储在类结构的function_table字段。
class Tipi{ public static function t() { echo 1; } } Tipi::t();
以上的代码在VLD扩展下生成的部分中间代码:
number of ops: 8 compiled vars: none line # * op fetch ext return operands ------------------------------------------------------------------------------- -- 2 0 > EXT_STMT 1 NOP 8 2 EXT_STMT 3 ZEND_INIT_STATIC_METHOD_CALL 'Tipi','t' 4 EXT_FCALL_BEGIN 5 DO_FCALL_BY_NAME 0 6 EXT_FCALL_END 9 7 > RETURN 1 branch: # 0; line: 2- 9; sop: 0; eop: 7 path #1: 0, Class Tipi: Function t: Finding entry points Branch analysis from position: 0
从以上的内容可以看出整个静态成员方法的调用是一个先查找方法再调用的过程。而对于调用操作,对应的中间代码为ZEND_INIT_STATIC_METHOD_CALL。由于类名和方法名都是常量,于是我们可以知道中间代码对应的函数是ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER。在这个函数中,它会首先调用zend_fetch_class函数,通过类名在EG(class_table)中查找类,然后再执行静态方法的获取方法。
if (ce->get_static_method) { EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); } else { EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); }
如果类结构中的get_static_method方法存在,则调用此方法,如果不存在,则调用zend_std_get_static_method。在PHP的源码中get_static_method方法一般都是NULL,这里我们重点查看zend_std_get_static_method函数。此函数会查找ce->function_table列表,在查找到方法后检查方法的访问控制权限,如果不允许访问,则报错,否则返回函数结构体。

To protect the application from session-related XSS attacks, the following measures are required: 1. Set the HttpOnly and Secure flags to protect the session cookies. 2. Export codes for all user inputs. 3. Implement content security policy (CSP) to limit script sources. Through these policies, session-related XSS attacks can be effectively protected and user data can be ensured.

Methods to optimize PHP session performance include: 1. Delay session start, 2. Use database to store sessions, 3. Compress session data, 4. Manage session life cycle, and 5. Implement session sharing. These strategies can significantly improve the efficiency of applications in high concurrency environments.

Thesession.gc_maxlifetimesettinginPHPdeterminesthelifespanofsessiondata,setinseconds.1)It'sconfiguredinphp.iniorviaini_set().2)Abalanceisneededtoavoidperformanceissuesandunexpectedlogouts.3)PHP'sgarbagecollectionisprobabilistic,influencedbygc_probabi

In PHP, you can use the session_name() function to configure the session name. The specific steps are as follows: 1. Use the session_name() function to set the session name, such as session_name("my_session"). 2. After setting the session name, call session_start() to start the session. Configuring session names can avoid session data conflicts between multiple applications and enhance security, but pay attention to the uniqueness, security, length and setting timing of session names.

The session ID should be regenerated regularly at login, before sensitive operations, and every 30 minutes. 1. Regenerate the session ID when logging in to prevent session fixed attacks. 2. Regenerate before sensitive operations to improve safety. 3. Regular regeneration reduces long-term utilization risks, but the user experience needs to be weighed.

Setting session cookie parameters in PHP can be achieved through the session_set_cookie_params() function. 1) Use this function to set parameters, such as expiration time, path, domain name, security flag, etc.; 2) Call session_start() to make the parameters take effect; 3) Dynamically adjust parameters according to needs, such as user login status; 4) Pay attention to setting secure and httponly flags to improve security.

The main purpose of using sessions in PHP is to maintain the status of the user between different pages. 1) The session is started through the session_start() function, creating a unique session ID and storing it in the user cookie. 2) Session data is saved on the server, allowing data to be passed between different requests, such as login status and shopping cart content.

How to share a session between subdomains? Implemented by setting session cookies for common domain names. 1. Set the domain of the session cookie to .example.com on the server side. 2. Choose the appropriate session storage method, such as memory, database or distributed cache. 3. Pass the session ID through cookies, and the server retrieves and updates the session data based on the ID.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

SublimeText3 English version
Recommended: Win version, supports code prompts!

WebStorm Mac version
Useful JavaScript development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

SublimeText3 Linux new version
SublimeText3 Linux latest version