Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Nie można nadpisać POST w ciele klasy?
Forum PHP.pl > Forum > PHP
markonix
Nie jest to jakoś szczególnie problematyczne ale nie umiem zrozumieć dlaczego tak jest. Kod:

  1. class jakakolwiek {
  2.  
  3. function __construct() {
  4.  
  5. $nazwaZmiennej = '_POST';
  6. $$nazwaZmiennej = array('test' => 'test nr 1');
  7. var_dump( $_POST );
  8.  
  9. $_POST = array('test2' => 'test nr 2');
  10. var_dump( $_POST );
  11.  
  12. }
  13.  
  14. }
  15.  
  16. $jakakolwiek = new jakakolwiek();


Powyższy kod wyświetli jedynie drugi fragment - tj. pierwszy var_dump wskaże, że $_POST jest puste.
Dlaczego tak się dzieje i dlaczego ten problem występuje wyłącznie w ciele klasy? Jeżeli napiszemy to poza klasą to działa zgodnie z założeniem.

Na ten problem natrafiłem gdy chciałem w aplikacji MVC przekazać do widoku zmienną _POST.
Bez MVC po prostu stosowałem $_POST = mysql_fetch_assoc(mysql_query(...
które w prosty sposób pobierało wartości domyślne do inputów (kod był poniżej update).
tolomei
Wychodzi na to, że mamy dwie zmienne - lokalną $_POST i superglobalną $_POST.

  1. class jakakolwiek {
  2. function __construct() {
  3. $nazwaZmiennej = '_POST';
  4. ${$nazwaZmiennej} = array('test' => 'test nr 1');
  5.  
  6. $_POST = array('test2' => 'test nr 2');
  7. }
  8. }
  9.  
  10. $j = new jakakolwiek();
  11. var_dump(get_defined_vars());


Ale nie wiem czemu tak smile.gif
solr
Cytat(markonix @ 1.04.2012, 20:14:15 ) *
Nie jest to jakoś szczególnie problematyczne ale nie umiem zrozumieć dlaczego tak jest. Kod:

  1. class jakakolwiek {
  2.  
  3. function __construct() {
  4.  
  5. $nazwaZmiennej = '_POST';
  6. $$nazwaZmiennej = array('test' => 'test nr 1');
  7. var_dump( $_POST );
  8.  
  9. $_POST = array('test2' => 'test nr 2');
  10. var_dump( $_POST );
  11.  
  12. }
  13.  
  14. }
  15.  
  16. $jakakolwiek = new jakakolwiek();


Powyższy kod wyświetli jedynie drugi fragment - tj. pierwszy var_dump wskaże, że $_POST jest puste.
Dlaczego tak się dzieje i dlaczego ten problem występuje wyłącznie w ciele klasy? Jeżeli napiszemy to poza klasą to działa zgodnie z założeniem.

Na ten problem natrafiłem gdy chciałem w aplikacji MVC przekazać do widoku zmienną _POST.
Bez MVC po prostu stosowałem $_POST = mysql_fetch_assoc(mysql_query(...
które w prosty sposób pobierało wartości domyślne do inputów (kod był poniżej update).


Minuta googlowania: http://www.php.net/manual/en/language.vari...uperglobals.php

"Note: Variable variables
Superglobals cannot be used as variable variables inside functions or class methods. "
markonix
Ok, dzięki.

Teraz pytanie jak to obejść i jakoś w widoku nadpisać ten POST.
Ostatecznie zrobię oddzielną tablicę $default ale nie każdy formularz buduje za pomocą klasy i zawsze to więcej kodu..
solr
Szczerze mówiąc nie rozumiem twojego problemu. Czemu zamiast:

  1. $nazwaZmiennej = '_POST';
  2. $$nazwaZmiennej = array('test' => 'test nr 1');
  3. var_dump( $_POST );


nie zrobisz po prostu:
  1. $_POST = array('test' => 'test nr 1');
  2. var_dump( $_POST );


ewentualnie, każdy element posta sprawdzić, czy jest i jak nie ma to wtedy dopisać wartość domyślną.
markonix
Normalnie bym tak zrobił ale w MVC wartości do widoku przekazuje w taki sposób:
$this->registry->template->_POST.
Fifi209
A czemu w ogóle chcesz nadpisywać?
markonix
Wyjaśniłem w drugiej części pierwszego postu.
#luq
W widoku nadpisać POST... Hm... jak już to złe miejsce na takie rzeczy.
Po 2, przekazuj tablic a nie działaj na gołej zmiennej superglobalnej w klasie, kiedyś będziesz chciał coś zmienić na GET, będziesz musiał zmieniać wszystkie wystąpienia POST, nawet w prostym IDE to nie problem ale jak dla mnie tak się robić po prostu nie powinno.

  1. $ret = Forms::valid($_POST, array(
  2. 'foo' => 1, // lista defaultowych zmiennych
  3. 'bar' => 2
  4. ));
  5. $this->view->assign('formValues', $ret);
markonix
W żadnym wypadku nie chciałem tego robić w widoku.
Często mniej jednak kusi aby to zrobić z kontrolerze (zapytanie SQL).

Przyglądam się Twojego przykładowi i chyba rozumiem.
Metoda valid zwraca dane z POST, a w przypadku ich braku (nie wysłany formularz) dane defaultowe.
Potem w widoku w inputach <?= $formValues['name']; ?>.
W sumie to od początku było to moją alternatywną opcją tylko po prostu:
  1. <?php
  2. if (!isset($_POST['submit']))
  3. $ret = array('pole' => 'wartosc_domyslna');
  4. else
  5. $res = $_POST;
  6. // $res do widoku.
Pilsener
Normalną praktyką jest używanie requesta, który zawiera żądania POST, GET, zmienne serwerowe itp. itd. etc.
Dostęp do tego w kontrolerze np. taki:
  1. $request = $this->getRequest();


Teraz możesz zmienną nadpisać/ustawić używając np. metody setParam. Jest to na pewno wygodniejsze niż korzystanie z "gołych" superglobalnych tablic.
markonix
Cytat(Pilsener @ 2.04.2012, 10:21:12 ) *
Normalną praktyką jest używanie requesta, który zawiera żądania POST, GET, zmienne serwerowe itp. itd. etc.

Ma to jakieś zalety ale czy to jest bezpieczne?
Jak dobrze rozumiem z kilku tablic generowana jest jedna.
Co jeżeli w POST i GET i mamy taki sam indeks?
Co gorsza tablicą SERVER możemy manipulować przez GET np. http_referer=XYZ.
Pilsener
Kwestia ustalenia ważności, np. post nadpisuje get ale już nie server, nie widzę też problemu by wyłączyć możliwość nadpisywania niekórych zmiennych nawet z wewnątrz kontrolera przy użyciu ->setParam, można też zmienne grupować albo inaczej obsługiwać nadpisywanie zmiennych.

Dodatkowo taki obiekt request wyposażamy w inne przydatne metody typu ->isPost czy np. sprawdzenie czy żądanie jest wysyłane ajaxem.

Wygodne to bo grupuje nam zmienne superglobalne i powiązane z nimi metody w jednym miejscu - a jak to okodujemy w szczegółach to już zależy od nas.
markonix
A miałoby sens set/get Param z drugim argumentem, który np. byłby defaultowo 'POST' i określałby do której tablicy się odwołujemy?

isPost to po prostu alias dla if($_POST) czy coś głębszego?
Pilsener
Z tego co wiem isPost() sprawdza po prostu, czy została wysłana tablica post i zwraca true albo false.

W np. Zend Frameworku drugi parametr to defaultowa wartość zmiennej, coś w stylu:
  1. $variable = $request->getParam('name','Zdzichu'); //jak nie przekazaliśmy nigdzie zmiennej "name" to domyślnie będzie to "Zdzichu" ;)


Natomiast ja to widzę bardziej tak:
  1. $name = $request->getPost()->name;
  2. $name = $request->getPost()->getParam('name');


Zależy, jak okodujemy.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.