Przekazywanie zmiennej globalnej

0

Hej, mam pewien problem z edycją zmiennej globalnej w PHP. Problem polega na tym, że mam pewną uniwersalną funkcje przyjmującą trzy parametry. Jako pierwszy parametr zakładam, że zostanie przesłana tablica, dwa kolejne parametry to tekst. Problem polega na tym, że chciałbym aby ta tablicą była zmienna globalna pobierana w funkcji 'rodzica'. Aktualnie jako parametr funkcji przesyłam zmienną globalną, a to w żaden sposób jej nie edytuje. Dopiero gdy konkretnie w funkcji wskaże, że ma edytować zmienną globalną, a nie swój parametr to zaczyna działać, jednak wtedy funkcja traci na swojej uniwersalności. Kawałek kodu:

<?php
$notifies = array('test' => 'dane');

test();

function test() {
    global $notifies;
    if(1==1) {
        showNotifications();
        // Przekazuje zmienną globalną jako argument funkcji
        addError($notifies, 'Problem', 'Error');
        showNotifications();
    }
}

function addError($list,$msg,$type) {
    $error = array($type => $msg);
    array_push($list, $error);
}


function showNotifications() {
    global $notifies;
    print_r($notifies);
}

Oto co zwraca:

Array
(
    [test] => dane
)
Array
(
    [test] => dane
)

Czy istnieje opcja aby prawidłowo przekazywać zmienną globalną jako parametr funkcji?

2

Nie odczytuj zmiennych globalnych z funkcji.

<?php
$notifies = ['test' => 'dane'];

test($notifies);

function test(array $notifies) {
    if (1==1) {
        showNotifications($notifies);
        $newNotifies = addError($notifies, 'Problem', 'Error');
        showNotifications($newNotifies);
    }
}

function addError(array $list, string $msg, string $type) {
    $error = array($type => $msg);
    array_push($list, $error);
    return $list;
}

function showNotifications(array $notifies) {
    print_r($notifies);
}
3
szewa90 napisał(a):

Czy jesteś w stanie wytłumaczyć mi bądź odesłać do odpowiedniego źródła z którego zrozumiem na czym polegał mój błąd?

Funkcje w PHP przyjmują arraye przez wartość (podobnie jak string, int, bool). Z tego co wiem tylko resource oraz obiekty są przekazywane tak, że zachowują referencje do początkowego obiektu.

function change(array $value) {
  $value[] = 3;
} 

$value = [2];
change($value);
$value == [2]; // still

Jest to inne, niż w pozostałych językach gdzie zmiana obiektu lub arraya.

Możesz to obejść na dwa sposoby:

  1. Zwrócić nowy array - zalecane
    function change(array $value) {
      $value[] = 3;
      return $value;
    } 
    
    $value = [2];
    $value = change($value);
    $value == [2, 3]; // changed
    
  2. Użyć "reference argument" - użyć tylko w rzadkich przypadkach
    function change(array &$value) {
      $value[] = 3;
    } 
    
    $value = [2];
    change($value);
    $value == [2, 3]; // changed
    
  3. Trzymać stan w obiekcie - najlepsze
    class Notifications {
      private array $notifications = [];
    
      public function addError(string $msg, $type) {
          $this->notifications[] = [$msg => $type];
      }
    
      public function show() {
          print_r($this->notifications);
      }
    }
    
    $notifies = new Notifications();
    
    test();
    
    function test() {
        global $notifies;
        if (1==1) {
            $notifies->show();
            $notifies->addError('Problem', 'Error');
            $notifies->show();
        }
    }
    
    
1
szewa90 napisał(a):

Dziękuje za wyczerpanie tematu, w mojej głowie utarło się, że jest to jednak referencja. Wszystko już jasne.

Tylko że to nie jest referencja. Nazywa się to "reference argument", ale referencją nie jest. To taki bardziej "out argument".

1 użytkowników online, w tym zalogowanych: 0, gości: 1