так как ДЕЙСТВИТЕЛЬНО работает передача по ссылке в php? - PullRequest
2 голосов
/ 28 декабря 2010

Действительно простой вопрос, но вместо того, чтобы просить академического объяснения, я хочу сохранить его как можно более прагматичным: когда PHP создаст копию моего огромного класса, я передаю в функцию, а когда он просто создаст указатель соответствующие данные? И если он все время создает указатели, какой смысл использовать & (кроме замыканий, очевидно)? Я полагаю, что недостаточно разбираюсь в смелости переводчика.

Ответы [ 4 ]

2 голосов
/ 28 декабря 2010

В PHP 5 все объекты передаются по их дескриптору.Проходите ли вы по ссылке или нет, не имеет значения с точки зрения производительности.(На самом деле, передача по ссылке в руководстве предупреждается как медленнее .) Объект, над которым вы работаете внутри функции, - это тот же объект, на который указывает вне функции.

КогдаВы передаете объект (дескриптор) по ссылке, затем можете изменить то, на что указывает внешняя переменная.Это почти всегда не нужно.

0 голосов
/ 28 декабря 2010

Вы можете найти множество способов передачи переменной по ссылке в руководстве по PHP. Один из лучших примеров - preg_match .

preg_match вернет количество вхождений, которым был сопоставлен шаблон во входной строке. Затем он заполняет, если это предусмотрено, ссылочный массив $matches, содержащий совпадения.

Это можно рассматривать как способ вернуть более одного значения, хотя вы должны быть осторожны с этим. За пример:

class Server {

    protected $_clientId = 0;

    protected $_clients = array();

    /**
     * Get a pending connection.
     *
     * @param &$connection_id int The connection identifier.
     * @return resource The socket resource.
     */
    public function getNextClient(&$connection_id) {
        $clientSocket = socket_accept($this->_server);     
        $connection_id = $this->_clientId++; 
        $this->_clients[$connection_id] = $clientSocket;
        return $clientSocket;
    }

}

$server = new Server;
$socket1 = $server->getNextClient($id);
echo $id; // 0
$socket2 = $server->getNextClient($id);
echo $id; // 1

Важное примечание. Объекты передаются по ссылке по умолчанию. Они не будут клонированы . Даже без указания & в аргументе функции изменение переданного объекта также приведет к изменению исходного объекта. Единственный способ предотвратить это - клонировать объект в функции / методе.

0 голосов
/ 28 декабря 2010

Зачем беспокоиться о &, даже если вы можете сделать это как угодно.Вот как я это делаю:

Предположим, у меня есть класс 'Book' с некоторыми общедоступными методами и свойствами, такими как title, author, year, для простого создания объекта:

$book = new Book()
// then I can use all public methods and properties

$book->title;

$book->author;

$book->year;

Если мне нравится, то я могу сделать подкласс, скажем,

class Novel extends Books{

  function buildIt(Book $bk){

      $bk->title;

      // so on 

  }

}

. В функции buildIt у меня специально есть объект класса Book 'параметр', в котором я могу передать весь объект класса 'Book'.

Надеюсь, это поможет.

0 голосов
/ 28 декабря 2010

Оператор & обозначает переменную как передаваемую по ссылке.

$x = 'Hello World';
echo($x);

function asdf(&$var){
  $var = 'Test';
}

asdf($x);
echo($x);

То же самое относится к присваиванию и почти любому другому выражению.Если он не передан или не назначен по ссылке, предположим, что он передан или назначен по значению.

...