2016-07-08 6 views
0

Я адаптировал веб-скрипт, который я написал, чтобы соответствовать моим потребностям для некоторых данных, которые мне нужно получить с сервера. Я запускаю этот сценарий с терминала, поэтому сообщения об ошибках являются полезной информацией.Продолжайте пузыриться внутри цикла в PHP

Основная часть кода - это цикл внутри цикла, и в этом цикле я вызываю функцию. В этой функции есть вызов в базу данных. Если есть проблема с подключением к базе данных, я могу поймать эту ошибку с помощью простого try {} catch(){}, но как я должен структурировать свой код, чтобы я мог просто пропустить эту итерацию и перейти к следующему элементу в цикле? Другими словами, сделайте continue только из функции.

Ниже я расскажу, как бы это сделать, но я не уверен, что это правильный путь.

foreach ($flavours as $icecream) { 
    foreach ($sauces as $sauce) { 
    $amount = dessertServings($icecream, $sauce); 
    if ($amount != null) { 
     // Some other functions like orderDessert, makePricingList and so on 
     fwrite(STDOUT, "$amount servings of $icecream with $sauce remaining!\n"); 
    } 
    } 
} 

dessertServings($icecream, $sauce) { 
    try { 
    $dbConnection = new Connection("user", "password", "db$icecream$sauce"); 
    $amountOfServings = $dbConnection->query($icecream, $sauce); 
    return $amountOfServings; 
    } 
    // E.g database connection could not be made 
    catch(Exception $e) { 
    fwrite(STDERR, $e->getMessage() . "\n"); 
    return; 
    } 
} 

Есть ли лучший способ сделать это?

Чтобы сделать все сложнее, Что делать, если функция фактически ничего не возвращает и, следовательно, не присваивает значение переменной? Как вы должны с этим справиться?

foreach ($flavours as $icecream) { 
    foreach ($sauces as $sauce) { 
    prepareDessert($icecream, $sauce); 
    // Other functions, most importantly: eatDessert($dessert) 
    } 
} 

prepareDessert($icecream, $sauce) { 
    try { 
    $dbConnection = new Connection("user", "password", "db$icecream$sauce"); 
    $dbConnection->query($icecream, $sauce)->do("prepare"); 
    } 
    // E.g database connection could not be made 
    catch(Exception $e) { 
    fwrite(STDERR, $e->getMessage() . "\n"); 
    } 
} 

В таком случае, как я могу убедиться, что, когда try выходит из строя, блок в цикле никогда не достигает других функций, мы не можем съесть крем льда, который не был подготовлен в первое место!

Можно ли использовать пустую переменную, которая просто возвращает true при успешном выполнении, а false и fail, и выполняет следующий код в основном блоке только на true? Или есть ли лучшее соглашение для этого в PHP?

+2

Только инициируйте одно подключение к базе данных, прежде чем вы начнете цикл. Используйте это одно соединение повсюду. Не имеет смысла создавать новое соединение с использованием тех же учетных данных для каждой итерации, когда вы можете просто сохранить свой первоначальный (при условии, что он будет успешным). – George

+0

Да, создайте свое соединение, если ему удастся запустить цикл, если он не сработает, тогда отобразите свою ошибку. –

+0

@George Улучшен пример. –

ответ

0

как я должен структурировать свой код так, что я могу просто пропустить эту итерацию и перейти к следующему пункту в петле

Первое правило обработки исключений: не делайте обработку исключений. Позвольте ему пузыриться и поймать его, когда вам это нужно (в вашем случае, в вашей петле).

Вы также можете перебросить исключение в свой catch, если хотите выполнить некоторую обработку внутри функции (например, print to STDERR), но пусть это пузырится!

Другим более традиционным методом является возврат функции к некорректному коду ошибки - самое основное, являющееся «истинным» по успеху, «ложное» или «нулевое» при неудаче, как в первом примере. Я не вижу в этом ничего плохого.

Чтобы сделать все сложнее, что, если функция фактически ничего не возвращает и, следовательно, не присваивает значение переменной? Как вы должны с этим справиться?

Бросайте исключения, это их работа!

как я убеждаюсь, что когда попытка не удается, то блок в цикле никогда не достигает других функций

Не пытайтесь/улов в пределах функции или повторно сгенерирует исключение изнутри ваш «улов».

Я бы использовал пустую переменную, которая просто возвращает true при успешном выполнении, а false и fail, и выполняет следующий код в основном блоке только на true? Или есть ли лучшее соглашение для этого в PHP?

Да, есть лучшее соглашение: бросить исключения.