Heim >Backend-Entwicklung >PHP-Tutorial >Beispielfreigabe für PHP-Ressourcentypen

Beispielfreigabe für PHP-Ressourcentypen

小云云
小云云Original
2018-03-15 14:48:201537Durchsuche

In PHP verwenden wir häufig Ressourcentypvariablen. Zum Beispiel: MySQL-Verbindung, Dateihandle usw. Diese Variablen können nicht durch Skalare dargestellt werden. Wie verbindet man also Ressourcenvariablen in PHP mit Ressourcen in der C-Sprache im Zend-Kernel?

1. Die Verwendung von Ressourcenvariablen in PHP

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


Ergebnisse drucken: Ressource(5) vom Typ (Stream )

Nummer 5: Zeigt an, dass die Ressourcen-ID 5 ist. Die spezifische Bedeutung wird später eingeführt.

stream: Name des Ressourcentyps.

2. Ressourcen-ID

Der Kernel speichert die registrierten Ressourcenvariablen in einer HashTable und verwendet den Schlüssel in der HashTable, in der sich die Ressource befindet, als Ressourcen-ID.

Tatsächlich speichert die Ressourcenvariable in PHP also tatsächlich eine Ganzzahl, und die entsprechende Ressource in der HashTable wird über diese ID gefunden.

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

Das obige Makro ist die API, die von ZE im Kernel verwendet wird, um Ressourcenvariablen Werte zuzuweisen eine Zuweisung an eine ganzzahlige Variable.

3. Ressourcentypname

Um Ressourcentypen zu unterscheiden, müssen wir Typnamen für die von uns definierten Ressourcen definieren.

#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) wird in PHP als SAPI (z. B. Apache) verfügbar sein mod_php5-Erweiterung) Beim Laden in den Speicher werden alle erweiterten ZEND_MINIT_FUNCTIONs ausgeführt.

Wobei jinyong der Name der aktuellen Erweiterung ist. Der Name der Erweiterung lautet derzeit beispielsweise jinyong

Zum leichteren Verständnis stellen wir uns das als die Erweiterung vor, die während der Initialisierung einen neuen Ressourcentyp beim Kernel registriert.

4. Ressourcenvariablen erstellen

Der Ressourcentyp wurde erfolgreich registriert und ein differenzierter Typname wurde für die Ressource definiert. Variablen für diese Ressource können jetzt verwendet werden.

Implementieren Sie die fopen-Funktion in PHP:

  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返回资源变量  
    }

Hier wird die Funktion namens my_fopen in PHP definiert. my_fopen(string $file_name, string $mode)

Implementiert die fclose-Funktion in PHP:

  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;  
    }

definiert den Namen in PHP als Die Funktion von my_fclose. my_fclose($resource)

5. Kompilieren und installieren Sie Erweiterungen, starten Sie php-fpm oder mod_php5 usw.

Methoden zur Verwendung benutzerdefinierter Erweiterungen in PHP

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

Kann Ressourcen normal öffnen und schließen.

7. Wir verwenden häufig Datenbankverbindungsressourcen und Dateihandle-Ressourcen, aber normalerweise müssen wir sie nicht manuell freigeben, und es treten keine Probleme mit Speicherverlusten auf.

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

Gehen Sie zurück zum ursprünglich registrierten Ressourcentyp und sehen Sie sich den ersten Parameter von zend_register_list_destructors_ex an, der der Zeiger auf den Destruktor ist.

Wenn Sie dann die automatische Freigabefunktion implementieren müssen, müssen Sie nur den Destruktor definieren und den Funktionszeiger übergeben.

Schauen Sie sich eine andere Frage an:

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


Definieren Sie den Destruktor:

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);  
}
  • In PHP speichern die sogenannten Ressourcenvariablen tatsächlich ganzzahlige Werte, suchen die entsprechenden Zeiger in der globalen Kernel-Ressourcenvariablenliste EG (regular_list) und führen entsprechende Operationen aus.

Der Ressourcentyp ist eine spezielle Variable, die einen Verweis auf eine externe Ressource enthält. Ressourcen werden durch spezielle Funktionen erstellt und genutzt.

Zum Beispiel Datenbankverbindung, Öffnen von Dateien, Grafikbereich usw.

Der Ressourcentyp ist eigentlich nur eine Ganzzahl, und der Kernel kann diesen Ganzzahlwert verwenden, um die endgültigen erforderlichen Daten an einem Ort zu finden, der einem Ressourcenpool ähnelt.

Beispiel 1, Beispiel für eine Dateioperation:

Codebeispiel:

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

Beispiel 2, Beispiel für eine Datenbankoperation:

Codebeispiel:

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

Beschreibung:
Liste der Funktionen zur Nutzung und Zerstörung von Ressourcen.
Sie können die Funktion is_resource() verwenden, um zu bestimmen, ob eine Variable eine Ressource ist, und die Funktion get_resource_type() gibt den Typ der Ressource zurück.

Was PHP-Ressourcenvariablen betrifft, müssen Sie sich keine Sorgen darüber machen, dass die MYSQL-Verbindung nicht freigegeben wird, da die Destruktormethode in der Erweiterung definiert ist, um sie automatisch freizugeben.

Verwandte Empfehlungen:

PHP-Ressourcenliste, PHP-Ressource_PHP-Tutorial

PHP-Ressourcen

Eine Zusammenfassung der PHP-Ressourcen, einschließlich: Bibliotheken, Frameworks, Vorlagen usw.

Das obige ist der detaillierte Inhalt vonBeispielfreigabe für PHP-Ressourcentypen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn