Dans le développement de PHP, la fonction Session_Register_Shutdown () est utilisée pour enregistrer une fonction de rappel qui est automatiquement exécutée lorsque la session est fermée. Bien que cette fonction existe dans certaines versions plus anciennes de PHP, dans des projets réels, en particulier lorsque vous maintenez le code hérité, vous pouvez rencontrer des situations où vous devez tester cette partie du code.
Puisque session_register_shutdown () lui-même est lié au mécanisme de session PHP, il est difficile de tester directement son comportement de rappel. Cet article présentera comment rédiger des structures de code testables et utiliser le cadre de test unitaire de PHP pour simuler ou remplacer session_register_shutdown () pour des tests efficaces.
session_register_shutdown () appellera la fonction de rappel enregistrée à la fin de l'exécution du script PHP. L'utilisation typique est la suivante:
<?php
session_register_shutdown(function() {
// Traitement de la logique lors de la fermeture d'une session
file_put_contents('session_log.txt', 'Session closed at ' . date('Y-m-d H:i:s'));
});
?>
Cette fonction de rappel sera automatiquement exécutée à la fin de la demande, ce qui donne l'environnement de test qu'il ne peut pas capturer directement ses résultats d'exécution.
Il est recommandé d'encapsuler la logique métier réelle dans une méthode distincte. Session_register_shutdown () n'est responsable que de l'enregistrement du rappel, et seule la méthode de la logique métier est appelée lors des tests.
<?php
class SessionHandler
{
public function registerShutdown()
{
session_register_shutdown([$this, 'onSessionShutdown']);
}
public function onSessionShutdown()
{
// Logique commerciale
file_put_contents('session_log.txt', 'Session closed at ' . date('Y-m-d H:i:s'));
}
}
?>
Lors des tests, nous n'appelons pas RegisterShutdown () , mais testons directement OnSessionShutdown () .
Les exemples de tests sont les suivants:
<?php
use PHPUnit\Framework\TestCase;
class SessionHandlerTest extends TestCase
{
protected $handler;
protected $logFile = __DIR__ . '/session_log.txt';
protected function setUp(): void
{
$this->handler = new SessionHandler();
// Assurez-vous que le fichier journal n'existe pas
if (file_exists($this->logFile)) {
unlink($this->logFile);
}
}
public function testOnSessionShutdownCreatesLog()
{
$this->handler->onSessionShutdown();
$this->assertFileExists($this->logFile);
$content = file_get_contents($this->logFile);
$this->assertStringContainsString('Session closed at', $content);
}
protected function tearDown(): void
{
if (file_exists($this->logFile)) {
unlink($this->logFile);
}
}
}
?>
En appelant directement les méthodes de logique métier, la complexité du test causée par le mécanisme de rappel est évitée.
Si vous souhaitez vous assurer que la fonction enregistrée est appelée dans le test, vous pouvez utiliser la technologie de remplacement de fonction ou de simulation, mais parce que session_register_shutdown () est une fonction intégrée PHP, il peut être difficile de se moquer directement. Les alternatives recommandées sont:
Résumé la fonction enregistrée en dépendances alternatives, telles que l'emballer avec des fermetures ou des interfaces.
Appelez la fonction réelle dans l'environnement de production et remplacez-la par une implémentation vide dans l'environnement de test.
Exemple:
<?php
class SessionHandler
{
private $registerShutdownCallback;
public function __construct(callable $registerShutdownCallback = null)
{
$this->registerShutdownCallback = $registerShutdownCallback ?: 'session_register_shutdown';
}
public function registerShutdown()
{
call_user_func($this->registerShutdownCallback, [$this, 'onSessionShutdown']);
}
public function onSessionShutdown()
{
// Logique commerciale
}
}
?>
Passez un rappel personnalisé pour remplacer session_register_shutdown lors des tests pour éviter les effets secondaires.
Il n'est pas recommandé de tester directement l'exécution de rappel de session_register_shutdown () .
Divisez la logique métier et testez le corps de la fonction de rappel séparément.
Améliorez la flexibilité des tests en remplaçant les appels de fonction intégrés par l'injection de dépendance.
Utilisez PHPUnit et d'autres cadres de test pour vérifier l'exactitude de la logique métier.
En utilisant la méthode ci-dessus, le code impliquant session_register_shutdown () peut être testé efficacement unité, améliorant la qualité et la maintenance du code.
<?php
class SessionHandler
{
private $registerShutdownCallback;
public function __construct(callable $registerShutdownCallback = null)
{
$this->registerShutdownCallback = $registerShutdownCallback ?: 'session_register_shutdown';
}
public function registerShutdown()
{
call_user_func($this->registerShutdownCallback, [$this, 'onSessionShutdown']);
}
public function onSessionShutdown()
{
// Simuler l'écriture de journaux
file_put_contents('https://m66.net/session_log.txt', 'Session closed at ' . date('Y-m-d H:i:s'));
}
}
// APPEL DE PRODUCTION
$handler = new SessionHandler();
$handler->registerShutdown();
?>
<?php
use PHPUnit\Framework\TestCase;
class SessionHandlerTest extends TestCase
{
protected $handler;
protected $logFile = __DIR__ . '/session_log.txt';
protected function setUp(): void
{
$this->handler = new SessionHandler(function ($callback) {
// La simulation n'effectue aucune opération,Évitez les effets secondaires
});
if (file_exists($this->logFile)) {
unlink($this->logFile);
}
}
public function testOnSessionShutdownCreatesLog()
{
$this->handler->onSessionShutdown();
$this->assertFileExists('https://m66.net/session_log.txt');
$content = file_get_contents('https://m66.net/session_log.txt');
$this->assertStringContainsString('Session closed at', $content);
}
protected function tearDown(): void
{
if (file_exists('https://m66.net/session_log.txt')) {
unlink('https://m66.net/session_log.txt');
}
}
}
?>