찾다
백엔드 개발PHP 튜토리얼PHP 리소스 유형 예시 공유
PHP 리소스 유형 예시 공유Mar 15, 2018 pm 02:48 PM
php공유하다

PHP에서는 리소스 유형 변수를 자주 사용합니다. 예: mysql 연결, 파일 핸들 등 이러한 변수는 스칼라로 표시할 수 없습니다. 그렇다면 PHP의 리소스 변수를 Zend 커널의 C 언어 리소스에 어떻게 연결합니까?

1. PHP에서 리소스 변수 사용

  1. $fp = fopen("test.txt", "rw");  
      
    var_dump($fp);  
      
    fclose($fp);


인쇄 결과: (스트림) 유형의 리소스(5)

숫자 5: 리소스 ID가 5임을 나타냅니다. 구체적인 의미가 소개됩니다. 나중에.

stream: 리소스 유형 이름.

2. 리소스 ID

커널은 등록된 리소스 변수를 HashTable에 저장하고, 리소스가 위치한 HashTable의 키를 리소스 ID로 사용합니다.

그래서 사실 PHP의 리소스 변수는 실제로 정수를 저장하는데, 이 ID를 통해 HashTable의 해당 리소스를 찾습니다.

  1. #define Z_RESVAL(zval)          (zval).value.lval  
    #define Z_RESVAL_P(zval)        Z_RESVAL(*zval)  
    #define Z_RESVAL_PP(zval)       Z_RESVAL(**zval)

위 매크로는 ZE가 커널에서 리소스 변수에 값을 할당하는데 사용하는 API인데 실제로는 정수변수에 대한 할당임을 알 수 있습니다.

3. 리소스 유형 이름

리소스 유형을 구별하려면 우리가 정의하는 리소스에 대한 유형 이름을 정의해야 합니다.

#define MY_RES_NAME "my_resource" //资源类型名称,PHP通过var_dump打印资源变量时会看到这个名称  
static int my_resource_descriptor;  
  
ZEND_MINIT_FUNCTION(jinyong)  
{  
    my_resource_descriptor = zend_register_list_destructors_ex(NULL, NULL, MY_RES_NAME, module_number);//向内核中注册新的资源类型  
}


ZEND_MINIT_FUNCTION(jinyong)은 PHP가 SAPI(예: Apache의 mod_php5 확장)로 메모리에 로드될 때 모든 확장의 ZEND_MINIT_FUNCTION을 실행합니다.

그 중 진영은 현재 확장자의 이름입니다. 예를 들어 이때 확장 이름은 jinyong

이해의 편의를 위해 초기화 시 커널에 새로운 리소스 유형을 등록하는 확장이라고 생각하면 됩니다.

4. 리소스 변수 생성

리소스 유형이 성공적으로 등록되었으며, 리소스에 대해 차별화된 유형 이름이 정의되었습니다. 이제 이 리소스의 변수를 사용할 수 있습니다.

PHP에서 fopen 함수 구현:

  1. PHP_FUNCTION(my_fopen)  
    {  
        zval *res;  
      
        char *filename, *mode;  
          
        int filename_strlen, mode_strlen;  
      
        FILE *fp;  
          
        if(zend_parse_parameters(ZEND_NUM_ARGS TSRMLS_CC, "s|s",  &filename, &filename_strlen, &mode, &mode_strlen) == FAILURE){  
            RETURN_FALSE;  
        }  
      
        //此处省略了对参数的有效性验证  
        fp = fopen(filename, mode);  
      
        ZEND_REGISTER_RESOURCE(res, fp, my_resource_descriptor);//向全局变量&EG(regular_list)中注册资源变量,并将对应HashTable的ID赋值给res  
      
        RETURN_RESOURCE(res);//向PHP返回资源变量  
    }

여기서 PHP에서 my_fopen이라는 함수가 정의됩니다. my_fopen(string $file_name, string $mode)

은 PHP에서 fclose 함수를 구현합니다.

  1. PHP_FUNCTION(my_fclose)  
    {  
        zval *res;  
          
        FILE *fp;  
      
        if(zend_parse_parameters(ZEND_NUM_ARGS TSRMS_CC, "r", &res) == FAILURE){  
            RETURN_FALSE;  
        }  
      
        if(Z_TYPE_P(res) == IS_RESOURCE){//判断变量类型是否是资源类型  
            zend_hash_index_del(&EG(regular_list), Z_RESVAL_P(res));//EG就类似于PHP中的$_GLOBALS。在全局资源变量regular_list中删除对应ID的资源  
        }else{  
            php_error_docref(NULL TSRMLS_CC, E_WARNING, "参数必须是资源类型变量");  
            RETURN_FALSE;  
        }  
      
        RETURN_TRUE;  
    }

은 PHP에서 my_fclose라는 함수를 정의합니다. my_fclose($resource)

5. 확장을 컴파일 및 설치하고 php-fpm 또는 mod_php5 등을 다시 시작합니다.

6. PHP

  1. my_fwrite($fp, "aaTest");  
      
    var_dump($fp);  
      
    my_fclose($fp);  
      
    var_dump($fp);

에서 사용자 정의 확장의 메서드를 사용하여 열고 닫습니다. 자원은 일반적으로 .

7. 우리는 PHP에서 데이터베이스 연결 리소스와 파일 핸들 리소스를 자주 사용하지만 일반적으로 이를 수동으로 해제할 필요가 없으며 메모리 누수 문제가 발생하지 않습니다.

  1. my_resource_descriptor = zend_register_list_destructors_ex(NULL, NULL, MY_RES_NAME, module_number);//向内核中注册新的资源类型

원래 등록된 리소스 유형으로 돌아가서 zend_register_list_destructors_ex의 첫 번째 매개변수를 확인하세요. 이 매개변수는 소멸자에 대한 포인터입니다.

그러다가 자동 해제 기능을 구현해야 한다면 소멸자를 정의하고 함수 포인터만 전달하면 됩니다.

다른 질문 보기:

  1. $fp = fopen("test.txt", "rw");  
      
    var_dump($fp);  
      
    //fclose($fp); 此处不使用fclose释放资源  
      
    unset($fp); //而是使用unset释放  
    //unset没有问题,会正常释放$fp变量。但$fp对应真正的打开文件资源句柄资源将永远释放不了,直至mod_php5或php-fpm重启  
    //可以看出,在注册资源类型时定义析构函数的必要性了


소멸자 정의:

static void php_myres_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC){//析构函数被调用时,会接受一个当前资源变量的参数  
    FILE *fp = (FILE*)rsrc->ptr;  
    fclose(fp);  
}  
  
ZEND_MINIT_FUNCTION(jinyong)  
{  
    my_resource_descriptor = zend_register_list_destructors_ex(php_myres_dtor, NULL, MY_RES_NAME, module_number);  
}
  • PHP에서 소위 리소스 변수는 실제로 커널 전역 리소스 변수 목록에 정수 값으로 저장됩니다. EG 찾기 (regular_list)의 해당 포인터를 찾아 해당 작업을 수행합니다.

리소스 유형은 외부 리소스에 대한 참조를 보유하는 특수 변수입니다. 리소스는 특화된 기능을 통해 생성되고 사용됩니다.

데이터베이스 연결, 파일 열기, 그래픽 캔버스 영역 등

리소스 유형은 실제로는 정수일 뿐이며, 커널은 이 정수 값을 기반으로 리소스 풀과 유사한 곳으로 이동하여 최종 필요한 데이터를 찾을 수 있습니다.

예제 1, 파일 연산 예시:

코드 예시:

<?php
$file=fopen(&#39;a.txt&#39;,&#39;r&#39;);//使用fopen函数打开一个文件获取句柄。  
fread($file,1024);//之后把该句柄传递给fread函数,即可对此文件进行后续操作。

예제 2, 데이터베이스 연산 예시:

코드 예시:

<?php
$result=mysql_query(&#39;select
 * from tbale&#39;);//mysql_query函数执行一条sql,若失败,返回false;成功,查询结果被缓存,并返回资源标识(类似:Resource
 id#42)即指向该资源的句柄。  
mysql_num_row($result);//使用该句柄可以操作缓存中的资源,从而返回查询出来的条数  
mysql_fetch_row($result);//使用该句柄可以操作缓存中的资源,从而返回查询结构

설명:
리소스를 사용하고 파기하는 함수 목록입니다.
is_resource() 함수를 사용하여 변수가 리소스인지 여부를 확인할 수 있으며, get_resource_type() 함수는 리소스 유형을 반환합니다.

PHP 리소스 변수의 경우 MYSQL 연결이 해제되지 않는 등의 문제에 대해 걱정할 필요가 없습니다. 소멸자 메서드가 확장에 정의되어 자동 해제를 돕기 때문입니다.

관련 추천:

PHP 리소스 목록, php resources_PHP 튜토리얼

PHP 리소스

라이브러리, 프레임워크, 템플릿 등을 포함한 PHP 리소스 요약

위 내용은 PHP 리소스 유형 예시 공유의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
php怎么把负数转为正整数php怎么把负数转为正整数Apr 19, 2022 pm 08:59 PM

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

php怎么实现几秒后执行一个函数php怎么实现几秒后执行一个函数Apr 24, 2022 pm 01:12 PM

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php字符串有没有下标php字符串有没有下标Apr 24, 2022 am 11:49 AM

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。

php怎么除以100保留两位小数php怎么除以100保留两位小数Apr 22, 2022 pm 06:23 PM

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

php怎么读取字符串后几个字符php怎么读取字符串后几个字符Apr 22, 2022 pm 08:31 PM

在php中,可以使用substr()函数来读取字符串后几个字符,只需要将该函数的第二个参数设置为负值,第三个参数省略即可;语法为“substr(字符串,-n)”,表示读取从字符串结尾处向前数第n个字符开始,直到字符串结尾的全部字符。

php怎么根据年月日判断是一年的第几天php怎么根据年月日判断是一年的第几天Apr 22, 2022 pm 05:02 PM

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

php怎么替换nbsp空格符php怎么替换nbsp空格符Apr 24, 2022 pm 02:55 PM

方法:1、用“str_replace("&nbsp;","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\&nbsp\;||\xc2\xa0)/","其他字符",$str)”语句。

php怎么查找字符串是第几位php怎么查找字符串是第几位Apr 22, 2022 pm 06:48 PM

查找方法:1、用strpos(),语法“strpos("字符串值","查找子串")+1”;2、用stripos(),语法“strpos("字符串值","查找子串")+1”。因为字符串是从0开始计数的,因此两个函数获取的位置需要进行加1处理。

See all articles

핫 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를 무료로 생성하십시오.

뜨거운 도구

mPDF

mPDF

mPDF는 UTF-8로 인코딩된 HTML에서 PDF 파일을 생성할 수 있는 PHP 라이브러리입니다. 원저자인 Ian Back은 자신의 웹 사이트에서 "즉시" PDF 파일을 출력하고 다양한 언어를 처리하기 위해 mPDF를 작성했습니다. HTML2FPDF와 같은 원본 스크립트보다 유니코드 글꼴을 사용할 때 속도가 느리고 더 큰 파일을 생성하지만 CSS 스타일 등을 지원하고 많은 개선 사항이 있습니다. RTL(아랍어, 히브리어), CJK(중국어, 일본어, 한국어)를 포함한 거의 모든 언어를 지원합니다. 중첩된 블록 수준 요소(예: P, DIV)를 지원합니다.

SecList

SecList

SecLists는 최고의 보안 테스터의 동반자입니다. 보안 평가 시 자주 사용되는 다양한 유형의 목록을 한 곳에 모아 놓은 것입니다. SecLists는 보안 테스터에게 필요할 수 있는 모든 목록을 편리하게 제공하여 보안 테스트를 더욱 효율적이고 생산적으로 만드는 데 도움이 됩니다. 목록 유형에는 사용자 이름, 비밀번호, URL, 퍼징 페이로드, 민감한 데이터 패턴, 웹 셸 등이 포함됩니다. 테스터는 이 저장소를 새로운 테스트 시스템으로 간단히 가져올 수 있으며 필요한 모든 유형의 목록에 액세스할 수 있습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

안전한 시험 브라우저

안전한 시험 브라우저

안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.

PhpStorm 맥 버전

PhpStorm 맥 버전

최신(2018.2.1) 전문 PHP 통합 개발 도구