백엔드 개발 PHP 튜토리얼 [번역][php 확장 개발 및 임베디드] 13장-php INI 설정

[번역][php 확장 개발 및 임베디드] 13장-php INI 설정

Feb 10, 2017 am 10:17 AM
php


INI 설정

및 이전 1장에서 본 슈퍼전역 변수 및 영구 상수와 마찬가지로 php.ini 값은 확장된 MINIT 블록에서 정의되어야 합니다. 그러나 다른 기능과 달리 INI 옵션의 정의는 간단한 시작/중지 줄로만 구성됩니다.

PHP_MINIT_FUNCTION(sample4)
{
    REGISTER_INI_ENTRIES();
    return SUCCESS;
}
PHP_MSHUTDOWN_FUNCTION(sample4)
{
    UNREGISTER_INI_ENTRIES();
    return SUCCESS;
}
로그인 후 복사

INI 설정 정의 및 액세스

INI 명령 자체는 소스 코드 파일의 MINIT 함수 위에 있습니다. , use 다음 매크로는 이 두 매크로 사이에 완전히 독립적으로 정의될 수 있습니다.

PHP_INI_BEIGN()
PHP_INI_END()
로그인 후 복사

이 두 매크로 함수는 ZEND_BEGIN_MODULE_GLOBALS()/ZEND_END_MODULE_GLOBALS()와 유사합니다. 그러나 이는 typdef 구조가 아니라 정적 데이터 인스턴스 정의를 위한 프레임워크 구성입니다.

static zend_ini_entry ini_entries[] = {
{0,0,NULL,0,NULL,NULL,NULL,NULL,NULL,0,NULL,0,0,NULL} };
로그인 후 복사

보시다시피 이는 zend_ini_entry 값의 벡터를 정의하고 빈 레코드로 끝납니다. 이는 앞서 본 정적과 동일합니다. 벡터 function_entry의 정의는 동일합니다.

간단한 INI 설정

이제 It을 사용한 INI 구조가 생겼습니다. INI 명령어와 INI 설정의 엔진 등록/제거 메커니즘을 정의하는 데 사용되므로 실제로 확장에 대한 일부 INI 명령어를 정의할 수 있습니다. 5장 "첫 번째와 동일합니다." 확장명"을 사용하지만 인사하고 싶다면 이를 사용자 정의할 수 있습니다.

PHP_FUNCTION(sample4_hello_world)
{
    php_printf("Hello World!\n");
}
로그인 후 복사

가장 간단하고 직접적인 방법은 INI 명령을 정의하고 기본값인 "Hello world! ":

#include "php_ini.h"
PHP_INI_BEGIN()
    PHP_INI_ENTRY("sample4.greeting", "Hello World",
                                    PHP_INI_ALL, NULL)
PHP_INI_END()
로그인 후 복사

짐작하셨겠지만, 이 매크로의 처음 두 매개변수는 매크로의 이름을 나타냅니다. INI 명령 및 해당 기본값 세 번째 매개변수는 엔진이 이 INI 명령을 수정하도록 허용하는지 여부를 결정하는 데 사용됩니다(이 장의 뒷부분에서 소개되는 액세스 수준 문제와 관련됨). INI 명령어의 값이 변경될 때마다 호출됩니다. 수정 이벤트 섹션에서 이 매개변수의 세부정보를 볼 수 있습니다. 원본 작업의 예상 결과와 일치하지 않는 결과가 나타나면 "REGISTER_INI_ENTRIES();"를 추가하세요. 테스트 중에 MINIT() 함수를 호출하고 MINIT에 전역 공간을 할당한 후 호출이 실행되는지 확인하세요.

이제 INI 설정이 정의되었으므로,

PHP_FUNCTION(sample4_hello_world)
{
    const char *greeting = INI_STR("sample4.greeting");
    php_printf("%s\n", greeting);
}
로그인 후 복사

꼭 사용해야 합니다. char * 값은 엔진이 소유하므로 수정해서는 안 됩니다. INI 설정 값을 const로 임시 저장하기 위해 로컬에서 사용하는 변수입니다. 물론 모든 INI 값이 문자열은 아닙니다. 정수, 부동 소수점 및 부울 값을 가져오는 다른 매크로가 있습니다. 🎜>

long lval = INI_INT("sample4.intval");
double dval = INI_FLT("sample4.fltval");
zend_bool bval = INI_BOOL("sample4.boolval");
로그인 후 복사

일반적으로 알고 싶은 것은 INI 설정의 현재 값입니다. 그러나 보충으로 사용할 수 있는 여러 매크로가 있습니다. INI 설정의 수정되지 않은 값 읽기:

const char *strval = INI_ORIG_STR("sample4.stringval");
long lval = INI_ORIG_INT("sample4.intval");
double dval = INI_ORIG_FLT("sample4.fltval");
zend_bool bval = INI_ORIG_BOOL("sample4.boolval");
로그인 후 복사

이 예에서 INI 명령 "sample4.greeting"의 이름에는 다른 확장에 의해 노출되는 INI 명령 이름과 충돌하지 않도록 확장자가 붙습니다. 이 접두사는 필수는 아니지만

액세스 수준

을 위한 공개 확장에 권장됩니다.

INI 지침에는 항상 기본값이 있습니다. 대부분의 경우 기본값을 변경하지 않고 그대로 두는 것이 이상적이지만 일부 특수한 상황이나 스크립트 내의 특정 작업에서는 이러한 값을 사용합니다. ​may 수정이 필요합니다. 아래 표와 같이 INI 명령어의 값은


에서 수정될 수 있습니다.


某些设置如果可以在任何地方被修改就没有多大意义了, 比如safe_mode, 如果可以在任何地方去修改, 那么恶意脚本的作者就可以很简单的去禁用safe_mode, 接着去读或修改本不允许操作的文件.

类似的, 某些非安全相关的指令比如register_globals或magic_quotes_gpc, 在脚本中不能被修改, 因为, 在脚本执行时, 它所影响的事情已经发生过了.

这些指令的访问控制是通过PHP_INI_ENTRY()的第三个参数完成的. 在你前面例子中, 使用了PHP_INI_ALL, 它的定义是一个位域操作: PHP_INI_SYSTEM | PHP_INI_PERDIR | PHP_INI_USER.

对于register_globals和magic_quotes_gpc这样的指令, 定义的访问级别为PHP_INI_SYSTEM | PHP_INI_PERDIR. 排除了PHP_INI_USER将导致以这个名字调用ini_set()时最终会失败.

现在, 你可能已经猜到, safe_mode和open_basedir这样的指令应该仅被定义为PHP_INI_SYSTEM. 这样的设置就确保了只有系统管理员可以修改这些值, 因为只有它们可以访问修改php.ini或httpd.conf文件中的配置.

修改事件

当INI指令被修改时, 无论是通过ini_set()函数还是某个perdir指令的处理, 引擎都会为其测试OnModify回调. 修改处理器可以使用ZEND_INI_MH()宏定义, 并通过在OnModify参数上传递函数名附加到INI指令上:

ZEND_INI_MH(php_sample4_modify_greeting)
{
    if (new_value_length == 0) {
        return FAILURE;
    }
    return SUCCESS;
}
PHP_INI_BEGIN()
    PHP_INI_ENTRY("sample4.greeting", "Hello World",
            PHP_INI_ALL, php_sample4_modify_greeting)
PHP_INI_END()
로그인 후 복사

通过在new_value_length为0时返回FAILURE, 这个修改处理器禁止将greeting设置为空字符串. ZEND_INI_MH()宏产生的整个原型如下:

int php_sample4_modify_greeting(zend_ini_entry *entry,
    char *new_value, uint new_value_length,
    void *mh_arg1, void *mh_arg2, void *mh_arg3,
    int stage TSRMLS_DC);
로그인 후 복사

各个参数的含义见下表:


액세스 수준

의미

SYSTEM

php.ini에 있습니다. , 또는 apachehttpd.conf 구성 파일 외부 지시문, 엔진 시동 단계에 영향 ,INI 세트"<🎜로 간주될 수 있습니다. >글로벌".

PERDIR

Apachehttpd.conf 구성 파일 <🎜에 있습니다. > 지시어 , 또는 디렉토리를 요청하거나 호스트 및 기타 apacheINI 아래에 스크립트가 .htaccess 파일이 있는 가상 디렉터리입니다. 요청을 처리하기 전에 다른 곳으로 설정 >COMMAND.

USER

스크립트 실행이 시작되면 , 은 사용자 공간 함수 ini_set( ) INI세트 .

参数名

含义

entry

은 엔진의 실제 저장된 INI 명령 항목을 가리킵니다.이 구조는 현재 value , 원래 값 , 해당 모듈이 속한 모듈 , 및 기타 아래코드(zend_ini_entry구조구조)등재정보

new_value

설정할 값.프로세서가 반환되는 경우SUCCESS,이 값은 entry->value,로 설정되며 entry->orig_value <인 경우 🎜>에는 현재 이 설정되어 있지 않습니다. 에서 현재 값을 entry->orig_value로 설정합니다. , entry->modified 태그 를 설정합니다.이 문자열의 길이는 다음과 같습니다. 통과 new_value_length통과.

mh_arg1, 2, 3

3 포인터는 INI 명령이 다음과 같을 때 제공되는 데이터 포인터에 해당합니다. 정의된 (zend_ini_entry3명의 동일한 이름).실제로는 ,이 값은 엔진에서 내부 처리를 위해 사용됩니다,신경쓰지 않아도 됩니다.

스테이지

ZEND_INI_STAGE_ 시리즈 5개 값 중 하나: STARTUP, SHUTDOWN, ACTIVATE, DEACTIVATE, RUNTIME 이 상수는 MINIT, MSHUTDOWN, RINIT, RSHUTDOWN, 및 활성 스크립트 실행 에 해당합니다. .


核心结构体: zend_ini_entry

struct _zend_ini_entry {
    int module_number;
    int modifiable;
    char *name;
    uint name_length;
    ZEND_INI_MH((*on_modify));
    void *mh_arg1;
    void *mh_arg2;
    void *mh_arg3;

    char *value;
    uint value_length;

    char *orig_value;
    uint orig_value_length;
    int modified;

    void ZEND_INI_DISP(*displayer);
};
로그인 후 복사

展示INI设置

在上一章, 你看到了MINFO函数以及相关的指令用于展示扩展的信息. 由于扩展暴露INI指令是很常见的, 因此引擎提供了一个公共的宏可以放置到PHP_MINFO_FUNCTION()中用于展示INI指令信息.

PHP_MINFO_FUNCTION(sample4)
{
    DISPLAY_INI_ENTRIES();
}
로그인 후 복사

这个宏将迭代PHP_INI_BEGIN()和PHP_INI_END()宏之间定义的INI指令集和, 在一个3列的表格中展示它们的INI指令名, 原始值(全局的), 以及当前值(经过PERDIR指令或ini_set()调用修改后)

默认情况下, 所有的指令都直接以其字符串形式输出. 对于某些指令, 比如布尔值以及用于语法高亮的颜色值, 则在展示处理时应用了其他格式. 这些格式是通过每个INI设置的显示处理器处理的, 它和你看到的OnModify一样是一个动态的回调函数指针.

显示处理器可以使用PHP_INI_ENTRY()宏的扩展版指定, 它接受一个额外的参数. 如果设置为NULL, 则使用展示字符串值的处理器作为默认处理器:

PHP_INI_ENTRY_EX("sample4.greeting", "Hello World", PHP_INI_ALL,
    php_sample4_modify_greeting, php_sample4_display_greeting)
로그인 후 복사

显然, 需要在INI设置定义之前声明这个函数. 和OnModify回调函数一样, 这可以通过一个包装宏以及少量编码完成:

#include "SAPI.h" /* needed for sapi_module */
PHP_INI_DISP(php_sample4_display_greeting)
{
    const char *value = ini_entry->value;

    /* 选择合适的当前值或原始值 */
    if (type == ZEND_INI_DISPLAY_ORIG &&
        ini_entry->modified) {
        value = ini_entry->orig_value;
    }

    /* 使得打招呼的字符串粗体显示(当以HTML方式输出时) */
    if (sapi_module.phpinfo_as_text) {
        php_printf("%s", value);
    } else {
        php_printf("<b>%s</b>", value);
    }
}
로그인 후 복사

绑定到扩展的全局空间

所有的INI指令都在Zend引擎内有一块存储空间, 可以用以跟踪脚本内的变更并进行请求外部的全局设置维护. 在这块存储空间中, 所有的INI指令都以字符串值存储. 你已经知道了, 这些值可以使用INI_INT(), INI_FLT(), INI_BOOL()等宏函数, 很简单的翻译成其他的标量类型.

这个查找和转换过程由于两个原因非常低效: 首先, 每次一个INI的值在获取时, 它必须通过名字在一个HashTable中进行定位. 这种查找方式对于仅在运行时编译的用户空间脚本而言是没有问题的, 但是对于已编译的机器代码源, 运行时做这个工作就毫无意义.

每次请求标量值的时候都需要将底层的字符串值转换到标量值是非常低效的. 因此我们使用你已经学习过的线程安全全局空间作为存储媒介, 每次INI指令值变更时更新它即可. 这样, 所有访问INI指令的代码都只需要查找你的线程安全全局空间结构体中的某个指针即可, 这样就获得了编译期优化的优点.

在你的php_sample4.h文件MODULE_GLOBALS结构体中增加const char *greeting; 接着更新sample4.c中的下面两个方法:

ZEND_INI_MH(php_sample4_modify_greeting)
{
    /* Disallow empty greetings */
    if (new_value_length == 0) {
        return FAILURE;
    }
    SAMPLE4_G(greeting) = new_value;
    return SUCCESS;
}
PHP_FUNCTION(sample4_hello_world)
{
    php_printf("%s\n", SAMPLE4_G(greeting));
}
로그인 후 복사

由于这是对INI访问的一种非常常见的优化方式, 因此引擎暴露了一组专门处理INI指令到全局变量的绑定宏:

STD_PHP_INI_ENTRY_EX("sample4.greeting", "Hello World",
    PHP_INI_ALL, OnUpdateStringUnempty, greeting,
    zend_sample4_globals, sample4_globals,
    php_sample4_display_greeting)
로그인 후 복사


这个宏执行和上面你自己的php_sample4_modify_greeting相同的工作, 但它不需要OnModify回调. 取而代之的是, 它使用了一个泛化的修改回调OnUpdateStringUnempty, 以及信息应该存储的空间. 如果要允许空的greeting指令值, 你可以直接指定OnUpdateString替代OnUpdateStringUnempty.

类似的, INI指令也可以绑定long, double, zend_bool的标量值. 在你的php_sample4.h中MODULE_GLOBALS结构体上增加几个字段:

long mylong;
double mydouble;
zend_bool mybool;
로그인 후 복사

现在在你的PHP_INI_BEGIN()/PHP_INI_END()代码块中使用STD_PHP_INI_ENTRY()宏创建新的INI指令, 它和对应的_EX版本的宏的区别只是显示处理器以及绑定到的值不同.

STD_PHP_INI_ENTRY("sample4.longval", "123",
    PHP_INI_ALL, OnUpdateLong, mylong,
    zend_sample4_globals, sample4_globals)
STD_PHP_INI_ENTRY("sample4.doubleval", "123.456",
    PHP_INI_ALL, OnUpdateDouble, mydouble,
    zend_sample4_globals, sample4_globals)
STD_PHP_INI_ENTRY("sample4.boolval", "1",
    PHP_INI_ALL, OnUpdateBool, mybool,
    zend_sample4_globals, sample4_globals)
로그인 후 복사

这里要注意, 如果调用了DISPLAY_INI_ENTRIES(), 布尔类型的INI指令"sample4.boolval"将和其他设置一样, 被显示为它的字符串值; 然而, 首选的布尔值指令应该被显示为"on"或"off". 要使用这些更加表意的显示, 你可以使用STD_PHP_INI_ENTRY_EX()宏并创建显示处理器, 或者使用另外一个宏:

STD_PHP_INI_BOOLEAN("sample4.boolval", "1",
    PHP_INI_ALL, OnUpdateBool, mybool,
    zend_sample4_globals *, sample4_globals)
로그인 후 복사

这个特定类型的宏是布尔类型特有的, 它提供的是将布尔值转换为"on"/"off"值的显示处理器.

小结

在本章, 你了解了php语言中最古老的特性之一的实现, 它也是阻碍php可移植的罪魁. 对于每个新的INI设置, 都会使得编写可移植代码变得更加复杂. 使用这些特性要非常慎重, 因为扩展以后时钟都要使用它了. 并且, 在使用时要注意不同系统间的行为一致性, 以免在维护时出现不可预期的状况.

接下来的三张, 我们将深入到流API, 开始使用流的实现层和包装操作, 上下文, 过滤器等.

以上就是[翻译][php扩展开发和嵌入式]第13章-php的INI设置 的内容,更多相关内容请关注PHP中文网(www.php.cn)!


본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Ubuntu 및 Debian용 PHP 8.4 설치 및 업그레이드 가이드 Ubuntu 및 Debian용 PHP 8.4 설치 및 업그레이드 가이드 Dec 24, 2024 pm 04:42 PM

PHP 8.4는 상당한 양의 기능 중단 및 제거를 통해 몇 가지 새로운 기능, 보안 개선 및 성능 개선을 제공합니다. 이 가이드에서는 Ubuntu, Debian 또는 해당 파생 제품에서 PHP 8.4를 설치하거나 PHP 8.4로 업그레이드하는 방법을 설명합니다.

PHP 개발을 위해 Visual Studio Code(VS Code)를 설정하는 방법 PHP 개발을 위해 Visual Studio Code(VS Code)를 설정하는 방법 Dec 20, 2024 am 11:31 AM

VS Code라고도 알려진 Visual Studio Code는 모든 주요 운영 체제에서 사용할 수 있는 무료 소스 코드 편집기 또는 통합 개발 환경(IDE)입니다. 다양한 프로그래밍 언어에 대한 대규모 확장 모음을 통해 VS Code는

PHP에서 HTML/XML을 어떻게 구문 분석하고 처리합니까? PHP에서 HTML/XML을 어떻게 구문 분석하고 처리합니까? Feb 07, 2025 am 11:57 AM

이 튜토리얼은 PHP를 사용하여 XML 문서를 효율적으로 처리하는 방법을 보여줍니다. XML (Extensible Markup Language)은 인간의 가독성과 기계 구문 분석을 위해 설계된 다목적 텍스트 기반 마크 업 언어입니다. 일반적으로 데이터 저장 AN에 사용됩니다

JWT (JSON Web Tokens) 및 PHP API의 사용 사례를 설명하십시오. JWT (JSON Web Tokens) 및 PHP API의 사용 사례를 설명하십시오. Apr 05, 2025 am 12:04 AM

JWT는 주로 신분증 인증 및 정보 교환을 위해 당사자간에 정보를 안전하게 전송하는 데 사용되는 JSON을 기반으로 한 개방형 표준입니다. 1. JWT는 헤더, 페이로드 및 서명의 세 부분으로 구성됩니다. 2. JWT의 작업 원칙에는 세 가지 단계가 포함됩니다. JWT 생성, JWT 확인 및 Parsing Payload. 3. PHP에서 인증에 JWT를 사용하면 JWT를 생성하고 확인할 수 있으며 사용자 역할 및 권한 정보가 고급 사용에 포함될 수 있습니다. 4. 일반적인 오류에는 서명 검증 실패, 토큰 만료 및 대형 페이로드가 포함됩니다. 디버깅 기술에는 디버깅 도구 및 로깅 사용이 포함됩니다. 5. 성능 최적화 및 모범 사례에는 적절한 시그니처 알고리즘 사용, 타당성 기간 설정 합리적,

문자열로 모음을 계산하는 PHP 프로그램 문자열로 모음을 계산하는 PHP 프로그램 Feb 07, 2025 pm 12:12 PM

문자열은 문자, 숫자 및 기호를 포함하여 일련의 문자입니다. 이 튜토리얼은 다른 방법을 사용하여 PHP의 주어진 문자열의 모음 수를 계산하는 방법을 배웁니다. 영어의 모음은 A, E, I, O, U이며 대문자 또는 소문자 일 수 있습니다. 모음이란 무엇입니까? 모음은 특정 발음을 나타내는 알파벳 문자입니다. 대문자와 소문자를 포함하여 영어에는 5 개의 모음이 있습니다. a, e, i, o, u 예 1 입력 : String = "Tutorialspoint" 출력 : 6 설명하다 문자열의 "Tutorialspoint"의 모음은 u, o, i, a, o, i입니다. 총 6 개의 위안이 있습니다

이전에 몰랐던 후회되는 PHP 함수 7가지 이전에 몰랐던 후회되는 PHP 함수 7가지 Nov 13, 2024 am 09:42 AM

숙련된 PHP 개발자라면 이미 그런 일을 해왔다는 느낌을 받을 것입니다. 귀하는 상당한 수의 애플리케이션을 개발하고, 수백만 줄의 코드를 디버깅하고, 여러 스크립트를 수정하여 작업을 수행했습니다.

PHP에서 늦은 정적 결합을 설명하십시오 (정적 : :). PHP에서 늦은 정적 결합을 설명하십시오 (정적 : :). Apr 03, 2025 am 12:04 AM

정적 바인딩 (정적 : :)는 PHP에서 늦은 정적 바인딩 (LSB)을 구현하여 클래스를 정의하는 대신 정적 컨텍스트에서 호출 클래스를 참조 할 수 있습니다. 1) 구문 분석 프로세스는 런타임에 수행됩니다. 2) 상속 관계에서 통화 클래스를 찾아보십시오. 3) 성능 오버 헤드를 가져올 수 있습니다.

php magic 방법 (__construct, __destruct, __call, __get, __set 등)이란 무엇이며 사용 사례를 제공합니까? php magic 방법 (__construct, __destruct, __call, __get, __set 등)이란 무엇이며 사용 사례를 제공합니까? Apr 03, 2025 am 12:03 AM

PHP의 마법 방법은 무엇입니까? PHP의 마법 방법은 다음과 같습니다. 1. \ _ \ _ Construct, 객체를 초기화하는 데 사용됩니다. 2. \ _ \ _ 파괴, 자원을 정리하는 데 사용됩니다. 3. \ _ \ _ 호출, 존재하지 않는 메소드 호출을 처리하십시오. 4. \ _ \ _ get, 동적 속성 액세스를 구현하십시오. 5. \ _ \ _ Set, 동적 속성 설정을 구현하십시오. 이러한 방법은 특정 상황에서 자동으로 호출되어 코드 유연성과 효율성을 향상시킵니다.

See all articles