Maison  >  Article  >  développement back-end  >  PHP : explication détaillée des exemples de types de données de ressources

PHP : explication détaillée des exemples de types de données de ressources

怪我咯
怪我咯original
2018-05-16 16:08:0718232parcourir

Que sont les types de données de ressources ?

Le type de données ressource est introduit dans PHP4. La ressource est un type de variable spécial qui contient une référence à une ressource externe : comme un fichier ouvert, une connexion à une base de données, une zone de canevas graphique, etc.

Les ressources sont créées et utilisées via des fonctions spécialisées.

Utilisation des variables de ressources en PHP

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

Résultat de l'impression : ressource(5) de type (stream)

Numéro 5 : Indique que l'ID de la ressource est 5, spécifiquement La signification sera introduite plus tard.

stream : nom du type de ressource.

ID de ressource

Le noyau stocke les variables de ressource enregistrées dans une HashTable et utilise la clé de la HashTable où se trouve la ressource comme ID de ressource.

Ainsi, en fait, la variable de ressource en PHP stocke en fait un entier, et la ressource correspondante dans la HashTable est trouvée via cet ID.

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

La macro ci-dessus est l'API utilisée par ZE dans le noyau pour attribuer des valeurs aux variables de ressources. On peut voir qu'il s'agit bien d'une affectation à une variable entière.

Nom du type de ressource

Afin de distinguer les types de ressources, nous devons définir des noms de type pour les ressources que nous définissons.

#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) exécutera tous les ZEND_MINIT_FUNCTION étendus lorsque PHP est chargé en mémoire en tant que SAPI (par exemple, l'extension mod_php5 d'Apache).

Où jinyong est le nom de l'extension actuelle. Par exemple, le nom de l'extension à l'heure actuelle est jinyong

Pour faciliter la compréhension, nous la considérons comme l'extension enregistrant un nouveau type de ressource auprès du noyau lors de l'initialisation.

Créer une variable de ressource

Le type de ressource a été enregistré avec succès et un nom de type distinctif a été défini pour la ressource. Les variables de cette ressource peuvent désormais être utilisées.

Implémentez la fonction fopen en PHP :

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

Ici, la fonction nommée my_fopen en PHP est définie. my_fopen(string $file_name, string $mode)

implémente la fonction fclose en PHP :

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

définit la fonction nommée my_fclose en PHP. my_fclose($resource)

En utilisant la méthode dans l'extension personnalisée en PHP

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

peut être ouvert et fermé normalement ressource.

Libérer des ressources

Le moteur PHP4 Zend introduisant un système de comptage de ressources, il peut détecter automatiquement qu'une ressource n'est plus référencée (tout comme Java). Dans ce cas, toutes les ressources externes utilisées par cette ressource seront libérées par le système de garbage collection. Par conséquent, il est rarement nécessaire de libérer manuellement de la mémoire à l’aide d’une fonction de résultat libre.

Remarque : les connexions persistantes à la base de données sont spéciales, elles ne seront pas détruites par le système de récupération de place.

Dans la section suivante, nous expliquerons la "valeur nulle (null) " parmi les deux types de données spéciaux.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn