12

[笔记] PHP源码-01

第一章笔记

宏定义里面的 # 妙用

  • ## 连接符,将两个语言符号组成单个符号
  • # 预处理运算符,将宏定义后面的宏参数进行字符串操作

多表达式宏定义 do-while 的妙用

#define TEST(a, b) a++;b++;

if (test_true)
    TEST(a, b);
else
    do_else();

一般情况下,在调用宏表达式时,在后面都会添加分号。在上面的例子中,宏表达式又破坏了if-else

结构,如果直接在宏定义中添加 { } 又不能编译通过。所以此时用do-while形式是很合适的。

#define TEST(a, b)      \
do  {                   \
a++;                    \
b++;                    \
} while(0)              \

if (test_true)
    TEST(a, b);
else
    do_else();

这样写的话,可以写多条表达式但是又不至于因为添加分号而造成的语法错误。

有时候do-while也用作空操作,比如条件编译或者在debug的时候如果是非调试模式,则将调试函数

定义为空。

line 预处理

php源码中的 ./php-src/Zend/zend_language_scanner.c文件中有这么一行:

#line 1112 "Zend/zend_language_scanner.c"

#line处理可以用于改变当前的文件名(__FILE__)和行数(__LINE__),便于调试。

php 全局变量宏

// php7.1.2
struct _php_core_globals {
    zend_bool implicit_flush;

    zend_long output_buffering;

    zend_bool enable_dl;

    char *output_handler;

    char *unserialize_callback_func;
    zend_long serialize_precision;

    zend_long memory_limit;
    zend_long max_input_time;

    zend_bool track_errors;
    zend_bool display_errors;
    zend_bool display_startup_errors;
    zend_bool log_errors;
    zend_long      log_errors_max_len;
    zend_bool ignore_repeated_errors;
    zend_bool ignore_repeated_source;
    zend_bool report_memleaks;
    char *error_log;

    char *doc_root;
    char *user_dir;
    char *include_path;
    char *open_basedir;
    char *extension_dir;
    char *php_binary;
    char *sys_temp_dir;

    char *upload_tmp_dir;
    zend_long upload_max_filesize;

    char *error_append_string;
    char *error_prepend_string;

    char *auto_prepend_file;
    char *auto_append_file;

    char *input_encoding;
    char *internal_encoding;
    char *output_encoding;

    arg_separators arg_separator;

    char *variables_order;

    HashTable rfc1867_protected_variables;

    short connection_status;
    short ignore_user_abort;

    unsigned char header_is_being_sent;

    zend_llist tick_functions;

    zval http_globals[6];

    zend_bool expose_php;

    zend_bool register_argc_argv;
    zend_bool auto_globals_jit;

    char *docref_root;
    char *docref_ext;

    zend_bool html_errors;
    zend_bool xmlrpc_errors;

    zend_long xmlrpc_error_number;

    zend_bool activated_auto_globals[8];

    zend_bool modules_activated;
    zend_bool file_uploads;
    zend_bool during_request_startup;
    zend_bool allow_url_fopen;
    zend_bool enable_post_data_reading;
    zend_bool report_zend_debug;

    int last_error_type;
    char *last_error_message;
    char *last_error_file;
    int  last_error_lineno;

    char *php_sys_temp_dir;

    char *disable_functions;
    char *disable_classes;
    zend_bool allow_url_include;
#ifdef PHP_WIN32
    zend_bool com_initialized;
#endif
    zend_long max_input_nesting_level;
    zend_long max_input_vars;
    zend_bool in_user_include;

    char *user_ini_filename;
    zend_long user_ini_cache_ttl;

    char *request_order;

    zend_bool mail_x_header;
    char *mail_log;

    zend_bool in_error_log;

#ifdef PHP_WIN32
    zend_bool windows_show_crt_warning;
#endif
};

上面这些php全局宏在相应的php.ini中大部分是有对应的。例如:

...
; display_errors
;   Default Value: On
;   Development Value: On
;   Production Value: Off

; display_startup_errors
;   Default Value: Off
;   Development Value: On
;   Production Value: Off

; error_reporting
;   Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
;   Development Value: E_ALL
;   Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT
...
[笔记] PHP源码-02