Php return без значения

Возврат метода PHP без значения

Я нахожусь на этапе перехода на 100% OO php, и у меня возникает множество подобных вопросов. Так что извините, если вы сочтете это глупым, я просто пытаюсь сделать свои методы объектно-ориентированного программирования хорошими с самого начала, чтобы мне не пришлось исправлять их позже.

private function _some_funct($args) < // Some code here. if ($something) return; //Rest of code >

В основном здесь есть 2 вопроса.

  1. Можно ли использовать return без значения после него? Я использую его МНОГОЕ и не замечал никаких недостатков, но никогда не видел этого в чужом коде. Я видел только return false .
  2. Можно ли вообще останавливать функции таким образом, или мне следует переосмыслить структуру моей программы?

Примером использования этого может быть CMS, которую я создаю.

public function _init_engines() < $this->_session_engine = $this->_dep['SessionEngine']; $this->_login_engine = $this->_dep['LoginEngine']; if ($this->_dep['User'] == false) return; $this->_security_engine = $this->_dep['SecurityEngine']; //Other engines go here. > 

Поэтому я позволяю системе запускать сеанс и настраивать переменные сеанса, а затем проверять, вошел ли пользователь в систему. Если пользователь не вошел в систему, LoginEngine позаботится об этом и загрузит модуль «Вход». После загрузки модуля входа в систему я не хочу создавать экземпляры других движков, поскольку они не нужны. Я мог бы использовать die или exit , но это остановило бы выполнение всего скрипта. Таким образом, мой скрипт завершает выполнение, и другие вещи, которые не являются движками, такие как тесты производительности и некоторые другие вещи, по-прежнему выполняются, а это как раз то, что я хочу. Опять же, следует ли мне пересмотреть свою логику здесь или это нормально, по вашему мнению?

Читайте также:  Php execute script file

Совершенно нормально использовать пустые возвраты для выхода из функции, но я обычно делаю это только в том случае, если указанная функция является функцией void (т. е. иначе ничего не возвращает) и не может быть реструктурирована, как Рэй. говорит.

3 ответа

return без значения допустим, если:

  1. В вашем интерфейсе это явно указано — в док-блоке указано @return void (если значение результата не требуется в функции) или что-то вроде @return sometype|null , где sometype равно string , int , и т.п.
  2. Код, который использует возвращаемые значения из таких функций / методов, проверяет isset() перед использованием возвращаемого значения — это может привести к ошибкам, если люди, использующие ваш код (или вы сами), забудут проверить его.

return без значения НЕ в порядке, если:

  1. Произошла ошибка — используйте исключения. С исключениями справиться намного проще, потому что вы можете:
    1. перехватывать их где угодно во внешней области видимости, даже глобально
    2. передавать приятные сообщения об ошибках
    3. расширить классы исключений для предоставления дополнительных функций
    4. проверить, какой именно тип исключения был выдан

    И, пожалуйста, никогда не используйте die() или exit() для «обработки» ошибок — показывать пользователям технические подробности ошибок — очень плохая практика.

    Что касается вашего метода _init_engines() — действительно трудно сказать, правильный он или неправильный, не зная остального.

    Если вас интересуют хорошие примеры ООП в PHP, я бы посоветовал взглянуть на Symfony.

    @return void не считается допустимым типом возврата в php подробнее здесь или этот ответ SO здесь или здесь

    Комментарий @Wilt, первая ссылка не работает, вторая была обновлена, чтобы показать, что теперь есть официальный RFC для типа void в PHP wiki.php.net/rfc/void_return_type

    @Джеймс, спасибо за ваш комментарий. Моему комментарию уже 4 года, так что я думаю, что-то изменилось. Мне придется по-новому прочитать то, что сегодня считается действительным.

    Для тех, кто читает эти комментарии, проверьте документы по типу возвращаемого значения void, которым поделился @James. , судя по всему, в PHP 7.1 возврат типа void реализован и считается действительным.

    Это касается религиозной битвы между единственной точкой возврата и множеством точек возврата, но мы идем .

    Использование многих возвратов без какого-либо значения или реальной необходимости в качестве управления потоком выполнения, чтобы избежать продолжения в функциях, является довольно плохой формой. Это что-то вроде волшебного лагеря операторов goto. Да, вы можете это сделать, но я бы проголосовал против того, чтобы на самом деле это делать, особенно если это не просто несколько возвратов на раннем этапе для короткого замыкания вашей функции для пары общих случаев.

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

     public function _init_engines() < $this->_session_engine = $this->_dep['SessionEngine']; $this->_login_engine = $this->_dep['LoginEngine']; if ($this->_dep['User'] != false)< $this->_security_engine = $this->_dep['SecurityEngine']; > else if () < //Other engines go here. >//no useless return needed > 

    Как говорили другие, в использовании return; нет недостатка. Обычно вы видите return false; , потому что обычно предпочтительно возвращать что-то значимое, когда это возможно, чтобы определить, что сделала функция. Если вы находитесь в состоянии «что бы он ни делал, все в порядке», тогда return; вполне приемлемо.

    Что касается множественного возврата, я предпочитаю использовать несколько точек выхода, когда условия достаточны, чтобы определить, что выполнение не должно продолжаться. Например, если вам требуется User ID , а вы его не получаете, возможно, нет смысла проверять остальные данные. В таком случае вы можете немедленно завершить функцию, введя что-то вроде return RES_INVALID_USERID . В таком случае я предпочитаю несколько return , чем цепочку из if..else (даже хуже, когда они вложены).

    Источник

    Php return без значения

    Значения возвращаются при помощи необязательного оператора возврата. Возвращаемые значения могут быть любого типа, в том числе это могут быть массивы и объекты. Возврат приводит к завершению выполнения функции и передаче управления обратно к той строке кода, в которой данная функция была вызвана. Для получения более детальной информации ознакомьтесь с описанием return .

    Замечание:

    Если конструкция return не указана, то функция вернёт значение null .

    Использование выражения return

    Пример #1 Использование конструкции return

    Функция не может возвращать несколько значений, но аналогичного результата можно добиться, возвращая массив.

    Пример #2 Возврат нескольких значений в виде массива

    function small_numbers ()
    return [ 0 , 1 , 2 ];
    >
    // Деструктуризация массива будет собирать каждый элемент массива индивидуально
    [ $zero , $one , $two ] = small_numbers ();

    // До версии 7.1.0 единственной эквивалентной альтернативой было использование конструкции list().
    list( $zero , $one , $two ) = small_numbers ();

    Для того, чтобы функция возвращала результат по ссылке, вам необходимо использовать оператор & и при описании функции, и при присвоении переменной возвращаемого значения:

    Пример #3 Возврат результата по ссылке

    Для получения более детальной информации о ссылках обратитесь к разделу документации Подробно о ссылках.

    User Contributed Notes 10 notes

    PHP 7.1 allows for void and null return types by preceding the type declaration with a ? — (e.g. function canReturnNullorString(): ?string)

    However resource is not allowed as a return type:

    function fileOpen ( string $fileName , string $mode ): resource
    $handle = fopen ( $fileName , $mode );
    if ( $handle !== false )
    return $handle ;
    >
    >

    $resourceHandle = fileOpen ( «myfile.txt» , «r» );
    ?>

    Errors with:
    Fatal error: Uncaught TypeError: Return value of fileOpen() must be an instance of resource, resource returned.

    Developers with a C background may expect pass by reference semantics for arrays. It may be surprising that pass by value is used for arrays just like scalars. Objects are implicitly passed by reference.

    # (1) Objects are always passed by reference and returned by reference

    function obj_inc_x ( $obj ) $obj -> x ++;
    return $obj ;
    >

    $obj2 = obj_inc_x ( $obj );
    obj_inc_x ( $obj2 );

    print $obj -> x . ‘, ‘ . $obj2 -> x . «\n» ;

    # (2) Scalars are not passed by reference or returned as such

    function scalar_inc_x ( $x ) $x ++;
    return $x ;
    >

    $x2 = scalar_inc_x ( $x );
    scalar_inc_x ( $x2 );

    # (3) You have to force pass by reference and return by reference on scalars

    $x2 =& scalar_ref_inc_x ( $x ); # Need reference here as well as the function sig
    scalar_ref_inc_x ( $x2 );

    # (4) Arrays use pass by value sematics just like scalars

    function array_inc_x ( $array ) $array < 'x' >++;
    return $array ;
    >

    $array = array();
    $array [ ‘x’ ] = 1 ;

    $array2 = array_inc_x ( $array );
    array_inc_x ( $array2 );

    print $array [ ‘x’ ] . ‘, ‘ . $array2 [ ‘x’ ] . «\n» ;

    # (5) You have to force pass by reference and return by reference on arrays

    $array = array();
    $array [ ‘x’ ] = 1 ;

    $array2 =& array_ref_inc_x ( $array ); # Need reference here as well as the function sig
    array_ref_inc_x ( $array2 );

    print $array [ ‘x’ ] . ‘, ‘ . $array2 [ ‘x’ ] . «\n» ;

    Be careful about using «do this thing or die()» logic in your return lines. It doesn’t work as you’d expect:

    function myfunc1 () return( ‘thingy’ or die( ‘otherthingy’ ));
    >
    function myfunc2 () return ‘thingy’ or die( ‘otherthingy’ );
    >
    function myfunc3 () return( ‘thingy’ ) or die( ‘otherthingy’ );
    >
    function myfunc4 () return ‘thingy’ or ‘otherthingy’ ;
    >
    function myfunc5 () $x = ‘thingy’ or ‘otherthingy’ ; return $x ;
    >
    echo myfunc1 (). «\n» . myfunc2 (). «\n» . myfunc3 (). «\n» . myfunc4 (). «\n» . myfunc5 (). «\n» ;
    ?>

    Only myfunc5() returns ‘thingy’ — the rest return 1.

    With 7.1, these are possible yet;

    function ret_void (): void // do something but no return any value
    // if needs to break fn exec for any reason simply write return;
    if (. ) return; // break
    // return null; // even this NO!
    >

    $db -> doSomething ();
    // no need return call anymore
    >

    function ret_nullable () ? int if (. ) return 123 ;
    > else return null ; // MUST!
    >
    >
    ?>

    Functions which return references, may return a NULL value. This is inconsistent with the fact that function parameters passed by reference can’t be passed as NULL (or in fact anything which isnt a variable).

    if ( testRet () === NULL )
    echo «NULL» ;
    >
    ?>

    parses fine and echoes NULL

    PHP 7 return types if specified can not return a null.
    For example:
    declare( strict_types = 1 );

    function add2ints ( int $x , int $y ): int
    $z = $x + $y ;
    if ( $z === 0 )
    return null ;
    >
    return $z ;
    >
    $a = add2ints ( 3 , 4 );
    echo is_null ( $a ) ? ‘Null’ : $a ;
    $b = add2ints (- 2 , 2 );
    echo is_null ( $b ) ? ‘Null’ : $b ;
    exit();

    Output :
    7
    Process finished with exit code 139

    Be careful when introducing return types to your code.

    Only one return type can be specified (but prefacing with ? allows null).

    Return values of a type different to that specified are silently converted with sometimes perplexing results. These can be tedious to find and will need rewriting, along with calling code.

    Declare strict types using «declare(strict_types=1);» and an error will be generated, saving much head-scratching.

    You may specify child return type if there is no parent:

    class A public function f ( $a )
    return 1 ;
    >
    >

    class B extends A public function f ( $a ): int // + return type, OK
    return 1 ;
    >
    >

    class C extends A public function f ( int $a ) // + argument type, WARNING
    return 1 ;
    >
    >
    ?>

    Note: the function does not have «alternative syntax» as if/endif, while/endwhile, and colon (:) here is used to define returning type and not to mark where the block statement begins.

    Declaring a collection of objects as return type is not implemented and forbidden:
    class Child <>

    function getChilds (): Child [] return [(new Child ()), (new Child ())];
    >

    var_dump ( getChilds ());
    // Returns: Parse error: syntax error, unexpected ‘[‘, expecting ‘ ?>

    We have to use:
    class Child <>

    function getChilds (): array
    return [(new Child ()), (new Child ())];
    >

    var_dump ( getChilds ());
    // Returns:
    /*
    array (size=2)
    0 =>
    object(Child)[168]
    1 =>
    object(Child)[398]*/
    ?>

    Idem for function parameter:
    function setChilds ( Child [] $childs )<>
    // Not allowed

    function setChilds (array $childs )<>
    // Allowed
    ?>

    Источник

Оцените статью