NotionCommotion Posted September 20, 2017 Share Posted September 20, 2017 Per http://php.net/manual/en/language.references.return.php Returning by reference is useful when you want to use a function to find to which variable a reference should be bound. Do not use return-by-reference to increase performance. The engine will automatically optimize this on its own. Only return references when you have a valid technical reason to do so. To return references, use this syntax: The following four examples are provided in the documentation. Example 2 makes perfect sense, but not really examples 1, 3, or 4. Can anyone shed some light on how the returned reference would be used? <?php //Example 1. http://php.net/manual/en/language.references.pass.php function foo(&$var) { $var++; } function &bar() { $a = 5; return $a; } foo(bar()); //Example 2. http://php.net/manual/en/language.references.return.php class foo { public $value = 42; public function &getValue() { return $this->value; } } $obj = new foo; $myValue = &$obj->getValue(); // $myValue is a reference to $obj->value, which is 42. $obj->value = 2; echo $myValue; // prints the new value of $obj->value, i.e. 2. //Example 3. http://php.net/manual/en/language.references.return.php function &collector1() { static $collection1 = array(); return $collection1; } $collection1 = &collector1(); $collection1[] = 'foo'; //Example 4. http://php.net/manual/en/language.references.return.php function &collector2() { static $collection2 = array(); return $collection2; } array_push(collector2(), 'foo'); Quote Link to comment Share on other sites More sharing options...
requinix Posted September 20, 2017 Share Posted September 20, 2017 Do you have specific questions or just want to understand what they're doing? #1 uses return-by-reference and pass-by-reference. It's just a trivial example to show both happening at once. One without the other and the code wouldn't work. #3 demonstrates a function using a static variable (so that all calls to it use the same variable) and return-by-reference (so that callers can modify the variable directly). Without the reference collector1() would have to provide some way to modify the value, but since it's a local static variable that means fun stuff like function collector1($key = null, $value = null, $addnull = false) { static $collection1 = array(); if ($value !== null || $addnull) { if ($key === null) { $collection1[] = $value; } else { $collection1[$key] = $value; } } }If you can't trust callers to manipulate $collection1 properly then you're forced into something like the above, but if you do can then it's much easier to use a reference. #4 is the same thing but without the temporary $collection1 variable. Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted September 20, 2017 Author Share Posted September 20, 2017 Thanks requinix, No specific question and just trying to understand them so I would know when to use them when the situation arrived. Your "fun" example helped. Quote Link to comment Share on other sites More sharing options...
kicken Posted September 21, 2017 Share Posted September 21, 2017 As a somewhat practical example of when you might want to return a reference, say for example you have a largish array tree (maybe something you json_decoded) and want to access it using a dot-separated path. You might have a function that can turn that path into a reference to that part of the tree which you could then manipulate if you wanted to. For example $config = [ 'doctrine' => [ 'dbal' => [ 'default_connection' => 'default' , 'connections' => [ 'default' => [ 'driver' => "%database_driver%" , 'host' => "%database_host%" , 'port' => "%database_port%" , 'dbname' => "%database_name%" , 'user' => "%database_user%" , 'password' => "%database_password%" , 'charset' => 'UTF8' ] , 'special' => [ 'driver' => "%database_driver%" , 'host' => "%database_host%" , 'port' => "%database_port%" , 'dbname' => "%database_name_special%" , 'user' => "%database_user_special%" , 'password' => "%database_password_special%" , 'charset' => 'UTF8' ] ] ] , 'orm' => [ 'default_entity_manager' => 'default' , 'auto_generate_proxy_classes' => "%kernel.debug%" , 'entity_managers' => [ 'default' => [ 'connection' => 'default' , 'naming_strategy' => 'doctrine.orm.naming_strategy.underscore' , 'mappings' => [ 'AppBundle' => [ 'type' => 'yml' , 'dir' => 'Resources/config/doctrine' , 'alias' => 'AppBundle' ] ] ] ] ] ] , 'swiftmailer' => [ 'transport' => "%mailer_transport%" , 'host' => "%mailer_host%" , 'username' => "%mailer_user%" , 'password' => "%mailer_password%" , 'spool' => ['type' => 'memory' ] ] ]; var_dump($config['doctrine']['dbal']['default_connection']); $connection = &getKey($config, 'doctrine.dbal.default_connection'); $connection = 'special'; var_dump($config['doctrine']['dbal']['default_connection']); function &getKey(&$config, $path){ if (strpos($path, '.') !== false){ list($key, $path) = explode('.', $path, 2); return getKey($config[$key], $path); } else { return $config[$path]; } } 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.