2010-03-29 5 views
5

Comment puis-je savoir si return() a été appelé depuis le fichier inclus. Le problème est que include() renvoie 'int 1', même si return() n'a pas été appelé. Voici un exemple ...PHP - Comment puis-je vérifier si return() a été appelé à partir d'un fichier include() 'd?

included_file_1.php

<?php 

return 1; 

included_file_2.php

<?php 

echo 'no return here, meep'; 

main.php

<?php 

$ret = include('included_file_1.php'); 

// This file DID return a value, int 1, but include() returns this value even if return() wasn't called in the included file. 
if ($ret === 1) 
{ 
    echo 'file did not return anything'; 
} 

var_dump($ret); 

$ret = include('included_file_2.php'); 

// The included file DID NOT return a value, but include() returns 'int 1' 
if ($ret === 1) 
{ 
    echo 'file did not return anything'; 
} 

var_dump($ret); 

Modifier: En tant que solution temporaire, j'attrape la sortie de include() (à partir d'instructions echo/print). Si une sortie a été produite, j'ignore la valeur de retour de include().

Pas joli, mais il offre les fonctionnalités dont j'ai besoin dans mon application web/framework.

Répondre

2

Bonne question. En regardant les exemples dans le manual, je suppose que vous ne pouvez pas.

La meilleure solution de contournement qui vient à l'esprit est de faire en sorte que toutes vos inclusions dans votre projet ne renvoient pas de valeurs nues, mais un tableau contenant la valeur de retour (return array(1);). Tout ce qui me vient à l'esprit (le mien au moins) implique de définir des constantes ou des variables pour marquer si vous êtes dans un include ou non. Rien d'élégant.

0

S'il n'y a rien à retourner dans le fichier inclus, alors la fonction d'inclusion renvoie 1 par défaut. Sinon, il retournera tout ce qui est envoyé par le fichier inclus. Les instructions d'écho et d'impression ne sont pas un retour, ce doit être l'instruction 'return' désignée par PHP. Tout le reste sera traité normalement. Ce code dit essentiellement, 'le fichier a-t-il été exécuté correctement?' et ça revient 1, 'oui ça l'a fait.' - Regardez «Handling Returns» juste en dessous des messages d'avertissement de sécurité, puis regardez l'exemple 5 et le texte juste en dessous. Cela explique tout parfaitement.

+0

Oui, mais si le script est inclus, include() retournera la valeur passée à return() dans le fichier inclus OR 'int 1' pour indiquer une inclusion réussie. Donc, quand include() renvoie 'int 1', je ne peux pas dire s'il s'agit d'une valeur de retour du fichier inclus ou include(). –

+0

Non-sens. Si vous CONNAISSEZ que le fichier renvoie sa propre valeur, vous pouvez supposer que la valeur est la valeur que vous vouliez qu'elle renvoie. Inclure ne remplacera jamais votre valeur de retour pour envoyer 1 qu'il a terminé. Il s'agit de savoir exactement ce que font vos fichiers et quelles sont les valeurs qui en découlent. Si vous savez que votre fichier ne renvoie rien, alors la valeur devrait toujours être 1. – animuson

+0

Animuson: Oui, mais je ne sais pas ce que font les autres fichiers. Il y aura également des cas de bords qui feront sauter le cadre, et seront un pita pour que quelqu'un d'autre puisse déboguer. –

1

Ce problème est inhérent à la conception - la déclaration include renvoie 1 lorsque le comprennent réussit (ou la valeur return « ed par le fichier inclus), que l'exécution du script peut se poursuivre même si un include échoue et un programmeur peut que vérifier pour ce cas.

A partir du manuel:

[la valeur de retour] est 1 parce que la comprennent a réussi. Notez la différence entre les exemples ci-dessus. La première utilise return() dans le fichier inclus tandis que l'autre fait non. Si le fichier ne peut pas être inclus, FALSE est renvoyé et E_WARNING est .

Dans ce cas, il suffit de ne pas utiliser 1 dans votre code comme une valeur de retour d'un fichier, à savoir, cette valeur de retour est effectivement réservé à l'usage par l'instruction PHP include.

+0

Cela pue, alors je ne serai pas en mesure de gérer gracieusement la sortie :(. Je suppose que ma seule alternative est de vérifier si include() produit une sortie (echo/print) .Si c'est le cas, alors je vais ignorer le –

0

$ ret = include ('...'); Renvoie toujours 1 si le fichier existe. Essayez de créer une variable et vérifiez si elle est définie.

include_file_1.php

<?php 
$includeFile1 = true; 

main.php

<?php 
include('included_file_1.php'); 

if (isset($includeFile1) == true) 
{ 
    echo "It was included"; 
} 
1

Vous pourriez probablement utiliser debug_backtrace(), mais ce n'est pas vraiment une solution idéale. C'est lent, et vous devrez faire beaucoup de travail pour obtenir les résultats que vous vouliez.

Malheureusement, la situation que vous décrivez est en dehors de l'utilisation habituelle de include et return. Je modifierais simplement votre logique pour travailler avec. Pourquoi ne pas avoir des fichiers qui n'appellent généralement pas return à la fin simplement appeler return 2? De cette façon, vous obtiendrez une valeur qui est toujours vraie sur des comparaisons normales, mais vous pouvez l'utiliser comme une distinction entre les autres appels return 1.

+0

Excellente idée avec 'debug_backtrace' - ne pensait pas à ça.Cependant, je ne pense pas que cela fonctionnera, car le fichier inclus ne laissera aucune trace (sans jeu de mots) dans le backtrace lorsqu'il est appelé après l'inclusion. –

+0

Zombat: Excellent conseil mais je debug_backtrace() saute sur include() et non dans. Mais, je pourrais utiliser eval() pour exécuter le code, avec un debug_backtrace() ajouté. Mais cette approche est trop compliquée et peut causer d'autres cas, plus difficiles à déboguer. Triste jour :(. –

0

jamais eu besoin, et ne savais que tu pouvais, mais je pourrais utiliser à la fin de chaque script inclus:

return __FILE__; 

ou:

return basename(__FILE__); 

ou si vous n'avez pas besoin cette spécificité, utilisez 2 comme suggéré plus tôt.

Questions connexes