search
HomeBackend DevelopmentPHP TutorialImplementation of type hints_PHP tutorial

Implementation of type hints

PHP is a weakly typed language, and data types are not strictly checked when passing parameters to methods. However, sometimes it is necessary to determine the parameters passed into the method. For this reason, PHP provides some functions to determine the type of data. For example, is_numeric() determines whether it is a numeric value or a string that can be converted into a numeric value, such as the type operator used to determine the object: instanceof. instanceof is used to determine whether a given object is from a specified object class. The instanceof operator was introduced in PHP 5. Before this, is_a() was used, but its use is no longer recommended.
In order to avoid problems caused by non-standard object types, the concept of type hints was introduced in PHP5. When defining method parameters, also define the object type of the parameters. If the type of the incoming parameter does not match the defined parameter type when calling, an error will be reported. In this way, the type of objects can be filtered, or the security of the data can be guaranteed.
The type hint function in PHP can only be used for hints whose parameters are objects, but cannot be used for type hints such as integers, strings, floating point, etc. After PHP5.1, PHP supports type hints for arrays.
To use type hints, just add the name of an existing class before the object type parameter of a method (or function). When using type hints, you can not only specify the object type, but also abstract classes and interfaces.
Type hint example for an array:
function array_print(Array $arr) {
print_r($arr);}
array_print(1);
There is a problem with the above code. It triggers the type hint we introduced this time. When this code is executed in versions after PHP5.1, the following error will be reported:
Catchable fatal error: Argument 1 passed to array_print() must be an array,
integer given, called in ...
When we change the integer variable in the function parameter into an array, the program will run normally and call the print_r function to output the array. So how is this type hint implemented? Whether it is a method in a class or a function we call, the function keyword is used as a mark of its declaration. The implementation of type hints is related to the declaration of the function. The type of the parameter is already determined at the time of declaration. Which, but will only be displayed when called. Here, we explain the implementation of type hints from two aspects:
Type hints when declaring parameters
Type hints when calling functions or methods
Modify the example just now:
function array_print(Array $arr = 1) {
print_r($arr);}
array_print(array(1));
Compared with the previous example, this code sets a default value for the function parameter, but this default value is an integer variable, which is different from the type hint Array given by the parameter. Therefore, when we run this When you snippet the code, you will quickly see that the program will report an error as follows:
Fatal error: Default value for parameters with array type hint
can only be an array or NULL
Why do you see the error so quickly? Because the detection process of the default value occurs in the intermediate code generation stage, unlike the error reporting at runtime, it has not yet generated the intermediate code, and there is no process of executing the intermediate code. In the Zend/zend_language_parser.y file, we find that the parameter list of the function will call the zend_do_receive_arg function at compile time. In the parameter list of this function, the fifth parameter (znode *class_type) is closely related to the type hint we want to describe in this section. The function of this parameter is to declare the type in the type hint. There are three types here:
Empty, that is, there is no type hint
Class name, user-defined or PHP-customized classes, interfaces, etc.
array, the corresponding token during compilation is T_ARRAY, which is Array string
In the zend_do_receive_arg function, a series of operations are performed on the class_type parameter, basically for the three types listed above. For the class name, the program does not determine whether the class exists, even if you use a different For existing class names, when the program reports an error, it will also be displayed that the object given by the actual parameter is not an instance of the given class.
The above is the process of declaring type hints and the process of judging the default value of parameters during the declaration process. Let's look at the implementation of type hints when calling functions or methods.
From the above declaration process, we know that PHP calls the zend_do_receive_arg function in the Zend/zend_complie.c file when compiling the code related to type hints. In this function, the opcode of the type hint judgment is assigned the value ZEND_RECV. According to the mapping calculation rules of opcode, it is concluded that ZEND_RECV_SPEC_HANDLER is called during execution. The code is as follows:
static int ZEND_FASTCALL ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS){
...//Omit
if (param == NULL) {
char *space;
char *class_name = get_active_class_name(&space TSRMLS_CC);
zend_execute_data *ptr = EX(prev_execute_data);
                                              if (zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL, opline->extended_value TSRMLS_CC)) {
               …//Omit
      }
          …//Omit
      } else {
            …//Omit
                zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value TSRMLS_CC);
           …//Omit
}
...//omitted}
As shown above: the last call in ZEND_RECV_SPEC_HANDLER is zend_verify_arg_type. The code is as follows:
static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zval *arg, ulong fetch_type TSRMLS_DC){
...//Omit
if (cur_arg_info->class_name) {
const char *class_name;
if (!arg) {
need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
Return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, "none", "" TSRMLS_CC);
}
if (Z_TYPE_P(arg) == IS_OBJECT) { // Since it is a class object parameter, the passed parameter needs to be an object type
// Next check whether this object is an instance object of the parameter prompt class. Here, it is allowed to pass subclass instance objects
need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
if (!ce || !instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) {
            return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, "instance of ", Z_OBJCE_P(arg)->name TSRMLS_CC);
}
} else if (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null) { // The parameter is NULL, which can also pass the check,
                                                                                                                                                                                                                        ​
need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
Return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, zend_zval_type_name(arg), "" TSRMLS_CC);
}
} else if (cur_arg_info->array_type_hint) { // Array
if (!arg) {
                                                                                                                                                                                                                                                          ;
}
if (Z_TYPE_P(arg) != IS_ARRAY && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) {
                                                                                                                                                                                                                                                                                              ;
}
}
return 1;}
The entire process of zend_verify_arg_type is shown in Figure 3.1:
Figure 3.1 Type prompt judgment flow chart
If the type hint reports an error, the zend_verify_arg_type function will finally call zend_verify_arg_class_kind to generate the error message, and call zend_verify_arg_error to report the error. The code is as follows:
static inline char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, ulong fetch_type, const char **class_name, zend_class_entry **pce TSRMLS_DC){
    *pce = zend_fetch_class(cur_arg_info->class_name, cur_arg_info->class_name_len, (fetch_type | ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD) TSRMLS_CC);
 
*class_name = (*pce) ? (*pce)->name: cur_arg_info->class_name;
if (*pce && (*pce)->ce_flags & ZEND_ACC_INTERFACE) {
    return "implement interface ";
} else {
    return "be an instance of ";
}}
 
 
static inline int zend_verify_arg_error(const zend_function *zf, zend_uint arg_num, const zend_arg_info *cur_arg_info, const char *need_msg, const char *need_kind, const char *given_msg, char *given_kind TSRMLS_DC){
    zend_execute_data *ptr = EG(current_execute_data)->prev_execute_data;
    char *fname = zf->common.function_name;
    char *fsep;
    char *fclass;
 
if (zf->common.scope) {
    fsep =  "::";
    fclass = zf->common.scope->name;
} else {
    fsep =  "";
    fclass = "";
}
 
if (ptr && ptr->op_array) {
    zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %s%s%s() must %s%s, %s%s given, called in %s on line %d and defined", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind, ptr->op_array->filename, ptr->opline->lineno);
} else {
    zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %s%s%s() must %s%s, %s%s given", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind);
}
return 0;}
在上面的代码中,我们可以找到前面的报错信息中的一些关键字Argument、 passed to、called in等。 这就是我们在调用函数或方法时类型提示显示错误信息的最终执行位置。

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/963684.htmlTechArticle类型提示的实现 PHP是弱类型语言,向方法传递参数时候也并不严格检查数据类型。 不过有时需要判断传递到方法中的参数,为此PHP中提供...
Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
What data can be stored in a PHP session?What data can be stored in a PHP session?May 02, 2025 am 12:17 AM

PHPsessionscanstorestrings,numbers,arrays,andobjects.1.Strings:textdatalikeusernames.2.Numbers:integersorfloatsforcounters.3.Arrays:listslikeshoppingcarts.4.Objects:complexstructuresthatareserialized.

How do you start a PHP session?How do you start a PHP session?May 02, 2025 am 12:16 AM

TostartaPHPsession,usesession_start()atthescript'sbeginning.1)Placeitbeforeanyoutputtosetthesessioncookie.2)Usesessionsforuserdatalikeloginstatusorshoppingcarts.3)RegeneratesessionIDstopreventfixationattacks.4)Considerusingadatabaseforsessionstoragei

What is session regeneration, and how does it improve security?What is session regeneration, and how does it improve security?May 02, 2025 am 12:15 AM

Session regeneration refers to generating a new session ID and invalidating the old ID when the user performs sensitive operations in case of session fixed attacks. The implementation steps include: 1. Detect sensitive operations, 2. Generate new session ID, 3. Destroy old session ID, 4. Update user-side session information.

What are some performance considerations when using PHP sessions?What are some performance considerations when using PHP sessions?May 02, 2025 am 12:11 AM

PHP sessions have a significant impact on application performance. Optimization methods include: 1. Use a database to store session data to improve response speed; 2. Reduce the use of session data and only store necessary information; 3. Use a non-blocking session processor to improve concurrency capabilities; 4. Adjust the session expiration time to balance user experience and server burden; 5. Use persistent sessions to reduce the number of data read and write times.

How do PHP sessions differ from cookies?How do PHP sessions differ from cookies?May 02, 2025 am 12:03 AM

PHPsessionsareserver-side,whilecookiesareclient-side.1)Sessionsstoredataontheserver,aremoresecure,andhandlelargerdata.2)Cookiesstoredataontheclient,arelesssecure,andlimitedinsize.Usesessionsforsensitivedataandcookiesfornon-sensitive,client-sidedata.

How does PHP identify a user's session?How does PHP identify a user's session?May 01, 2025 am 12:23 AM

PHPidentifiesauser'ssessionusingsessioncookiesandsessionIDs.1)Whensession_start()iscalled,PHPgeneratesauniquesessionIDstoredinacookienamedPHPSESSIDontheuser'sbrowser.2)ThisIDallowsPHPtoretrievesessiondatafromtheserver.

What are some best practices for securing PHP sessions?What are some best practices for securing PHP sessions?May 01, 2025 am 12:22 AM

The security of PHP sessions can be achieved through the following measures: 1. Use session_regenerate_id() to regenerate the session ID when the user logs in or is an important operation. 2. Encrypt the transmission session ID through the HTTPS protocol. 3. Use session_save_path() to specify the secure directory to store session data and set permissions correctly.

Where are PHP session files stored by default?Where are PHP session files stored by default?May 01, 2025 am 12:15 AM

PHPsessionfilesarestoredinthedirectoryspecifiedbysession.save_path,typically/tmponUnix-likesystemsorC:\Windows\TemponWindows.Tocustomizethis:1)Usesession_save_path()tosetacustomdirectory,ensuringit'swritable;2)Verifythecustomdirectoryexistsandiswrita

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

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

Hot Tools

VSCode Windows 64-bit Download

VSCode Windows 64-bit Download

A free and powerful IDE editor launched by Microsoft

MantisBT

MantisBT

Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

mPDF

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),