Bora ajudar o programador a transformar café em código?

Passagem por Valor e Passagem por Referência: Escopo de uma função

Neste tutorial de nosso curso de PHP, vamos aprender como passar argumentos para funções de duas maneiras distintas: passagem por valor e passagem por referência, além de entendermos o escopo de uma função.


O Escopo de uma Função

Vamos criar um script PHP simples, para te explicar o escopo de uma função,
Vamos definir o valor de uma variável:

$a=1;

Em seguida, invocamos uma função dobra(), que recebe $a como argumento, dobra seu valor internamente.

Em seguida, após chamar a função, exibimos o valor de $a.
Ora, como era 1 e dobramos, deve ser 2, correto?

Teste o script:

<html>
 <head>
  <title>Apostila PHP Progressivo</title>
 </head>
 <body>
 <?php
  $a=1;
  dobra($a);
  echo $a;
  
  function dobra($a){
   $a *= 2;
  }
 ?>
 </body>
</html>

E o resultado é....que runfem os tambores (sempre quis dizer isso)...tcharam...1 !
Isso mesmo, 1!

Ué, mas não tínhamos dobrado?
Na verdade, dobramos OUTRA variável, uma cópia dela...as coisas dentro do escopo de uma função são bem diferentes do que imaginávamos.
Vamos entender melhor.

Passagem por Valor em funções PHP

Quando passamos uma variável como argumento para uma função, a função vai e cria uma CÓPIA dela e passa a trabalhar com ela.

Quando passou $a=1, a função criou outra variável, QUE SÓ EXISTE INTERNAMENTE, copiou o valor 1 e passou a trabalhar com ela.

Essa passagem é chamada por valor, pois passamos só o VALOR para a função, não a variável em si.
Para fazer a função se comunicar com o mundo externo, devemos fazer ela dar um return com seu resultado final, ao passo que fazemos $a receber o retorno dessa função:

Passagem por Referência
E se quisermos passar a variável em si, para que ela seja alterada dentro do escopo da função?
Tem como fazer? Tem sim, via passagem por referência.

Para passar uma variável por referência, basta colocarmos o símbolo & antes do nome da variável, assim: &$a

Vamos refazer o primeiro exemplo, agora com passagem por referência:

<html>
 <head>
  <title>Apostila PHP Progressivo</title>
 </head>
 <body>
 <?php
  $a=1;
  dobra($a);
  echo $a;
  
  function dobra(&$a){
   $a *= 2;
  }
 ?>
 </body>
</html>

Veja que o valor de $a realmente se alterou e agora é 2!

Isso acontece porque passamos uma referência, o endereço de memória da variável $a, assim, todas as alterações feitas nessa variável, serão feitas diretamente na variável. Tudo isso graças ao operador &.

Então resumindo:
  1. Passagem por valor: os argumentos não são alterados, dentro da função se trabalha com uma cópia dessas variáveis, só o que importa é o valor delas. Se quiser mudar algo, use return para alterar fora da função
  2. Passagem por referência: usamos o operador & que dá acesso diretamente a variável, assim a função vai trabalhar com as variáveis diretamente, alterando seu valor. Geralmente, não se usa return quando se trabalha assim, pois alterações fora da função já estão sendo feitas

Mais escopo de funções

Vamos criar um script onde definimos uma variável:
$curso="PHP Progressivo";

E vamos invocar a função exibe(), que não recebe argumento nenhum, apenas dá um echo na variável $curso:

<html>
 <head>
  <title>Apostila PHP Progressivo</title>
 </head>
 <body>
 <?php
  $curso="PHP Progressivo";
   
  function exibe(){
   echo $curso;
  }
 ?>
 </body>
</html>

Note o que aconteceu: nada.

Isso porque a função é um mundo a parte, ela não sabe nada do que está acontecendo fora dela.
Ela só tem duas maneiras de comunicação:
Via parâmetros, recebendo argumentos, seja por valor ou referência
Enviando informações vi return

Se a variável $curso não foi passada para ela, ela não sabe o que é isso, nunca viu, nem ouviu.
A função só tem acesso aquilo que você passar para ela de informação, ok?

Veja também

O melhor PC para programar

O melhor celular para programar