2012-03-26 5 views
5

Ich benutze redis als Zwischenspeicher durch phpredis. Es funktioniert perfekt und ich möchte eine ausfallsichere Möglichkeit bieten, um sicherzustellen, dass die Caching-Funktion immer verfügbar ist (z. B. durch dateibasiertes Caching), selbst wenn der Redis-Server ausfällt, habe ich zunächst folgenden Code erstellt:Warum funktioniert Try/Catch in der phpredis connect-Funktion nicht?

<?php 
    $redis=new Redis(); 
    try { 
     $redis->connect('127.0.0.1', 6379); 
    } catch (Exception $e) { 
     // tried changing to RedisException, didn't work either 
     // insert codes that'll deal with situations when connection to the redis server is not good 
     die("Cannot connect to redis server:".$e->getMessage()); 
    } 
    $redis->setex('somekey', 60, 'some value'); 

Aber wenn redis Server heruntergefahren ist, bekam ich

PHP Fatal error: Uncaught exception 'RedisException' with message 'Redis server went away' in /var/www/2.php:10 
Stack trace: 
#0 /var/www/2.php(10): Redis->setex('somekey', 60, 'some value') 
#1 {main} 
    thrown in /var/www/2.php on line 10 

der Code der catch-Block nicht ausgeführt bekam. Ich ging zurück, um die phpredis doc zu lesen und kam stattdessen mit folgenden Lösung bis

<?php 
    $redis=new Redis(); 
    $connected= $redis->connect('127.0.0.1', 6379); 
    if(!$connected) { 
     // some other code to handle connection problem 
     die("Cannot connect to redis server.\n"); 
    } 
    $redis->setex('somekey', 60, 'some value'); 

Ich kann damit leben, aber meine Neugier würde nie zufrieden bekommen, so kommt hier meine Frage: warum die try/catch-Methode nicht den Fall ist arbeite mit dem Verbindungsfehler?

+1

'$ völlig neu zu> connect();' Es wird keine Ausnahme ausgelöst, wenn eine Verbindung einfach fehlschlägt. Was Sie tun können, ist zu überprüfen, ob $ redisse === true ist, wenn es wahr ist, dann sind Sie verbunden, sonst sind Sie nicht verbunden. Aber wie Nicolas unten bemerkt, ist die Ausnahme oben von setex, daher wird sie nicht eingefangen, es sei denn, du legst sie in den try catch-Block. – Haluk

+0

@haluk Redis connect-Methode löst eine Ausnahme aus. –

Antwort

3

Ihre Ausnahme wurde von setex gesendet, die sich außerhalb des try {} -Blocks befindet. Setzen Sie den Setex in den Try-Block und die Ausnahme wird gefangen.

+0

Ich denke, er erwartet eine Ausnahme zu bekommen, wenn der Dienst nicht verfügbar ist, zusammen mit dem für einen missgebildeten Befehl. – Niloct

+1

@Nilact, du liest meine Gedanken: D In der Tat wäre es nett, wenn beim Aufruf von connect() eine Ausnahme abgefangen werden kann. – ricochen

0

Wie Nicolas sagte, kommt die Ausnahme von SETEX, aber Sie können mit Hilfe des ping Befehl, dass (und sogar die try/catch-Block) vermeiden:

$redis=new Redis(); 
$redis->connect('127.0.0.1', 6379); 

if(!$redis->ping()) 
{ 
    die("Cannot connect to redis server.\n"); 
} 

$redis->setex('somekey', 60, 'some value'); 
+6

Danke für Ihre Antwort, aber ich sehe nicht, warum die Verwendung eines zusätzlichen Befehls (Ping in Ihrer Antwort) besser ist, als nur nach dem Ergebnis von connect() zu suchen, was ich tatsächlich in meinem Code verwende. – ricochen