$el = array_shift($instance->find(..))
Powyższy kod w jakiś sposób zgłasza ostrzeżenie o surowych standardach, ale to nie będzie:
function get_arr(){
return array(1, 2);
}
$el = array_shift(get_arr());
Więc kiedy i tak zgłosi ostrzeżenie?
get_arr()
funkcja) nie wytwarzają ścisłe zawiadomienie norm (testowane PHP 5.2 oraz PHP 5.5).Odpowiedzi:
Rozważ następujący kod:
error_reporting(E_STRICT); class test { function test_arr(&$a) { var_dump($a); } function get_arr() { return array(1, 2); } } $t = new test; $t->test_arr($t->get_arr());
Spowoduje to wygenerowanie następującego wyniku:
Strict Standards: Only variables should be passed by reference in `test.php` on line 14 array(2) { [0]=> int(1) [1]=> int(2) }
Powód?
test::get_arr()
Metoda nie jest zmienna i w trybie ścisłym spowoduje to wygenerowanie ostrzeżenia. To zachowanie jest wyjątkowo nieintuicyjne, ponieważget_arr()
metoda zwraca wartość tablicy.Aby obejść ten błąd w trybie ścisłym, zmień podpis metody, aby nie używała odwołania:
function test_arr($a) { var_dump($a); }
Ponieważ nie możesz zmienić podpisu
array_shift
, możesz również użyć zmiennej pośredniej:$inter = get_arr(); $el = array_shift($inter);
źródło
current
zakłada, że wskaźnik tablicy znajduje się na pierwszym elemencie. W większości przypadków może to być uzasadnione założenie, ale należy na nie uważać.array_shift()
w przypadku, gdy oczekuje się odniesienia do modyfikacji :-)$intermediate
wartości, używając dodatkowej pary nawiasów.$el = array_shift( ( get_arr() ) );
. Zobacz stackoverflow.com/questions/9848295/…$instance->find()
zwraca odniesienie do zmiennej.Otrzymujesz raport, gdy próbujesz użyć tego odwołania jako argumentu funkcji, bez wcześniejszego zapisywania go w zmiennej.
Pomaga to zapobiegać wyciekom pamięci i prawdopodobnie stanie się błędem w następnych wersjach PHP.
Twój drugi blok kodu zwróciłby błąd, gdyby napisał (zwróć uwagę na
&
podpis funkcji):function &get_arr(){ return array(1, 2); } $el = array_shift(get_arr());
Tak więc szybką (i niezbyt przyjemną) poprawką byłoby:
$el = array_shift($tmp = $instance->find(..));
Zasadniczo najpierw należy przypisać zmienną tymczasową i wysłać ją jako argument.
źródło
array_shift($tmp = $instance->find(..))
przypisuje wartość$instance->find(..)
do,$tmp
a następnie przekazuje wartość przypisania doarray_shift()
- co nie jest tym samym, co przekazanie$tmp
samego siebie, więc nie jest lepsze niż pierwotna sytuacja bez przypisania.Przyczyną błędu jest użycie wewnętrznej funkcji programowania struktur danych PHP, array_shift () [php.net/end].
Funkcja przyjmuje tablicę jako parametr. Chociaż znak ampersand jest wskazany w prototypie
array_shift()
w podręczniku ”, w rozszerzonej definicji tej funkcji nie ma żadnej dokumentacji ostrzegawczej ani wyraźnego wyjaśnienia, że parametr jest w rzeczywistości przekazywany przez odniesienie.Być może jest to / zrozumiane /. Nie rozumiałem jednak, więc trudno było mi wykryć przyczynę błędu.
Powiel kod:
function get_arr() { return array(1, 2); } $array = get_arr(); $el = array_shift($array);
źródło
Ten kod:
$monthly_index = array_shift(unpack('H*', date('m/Y')));
Należy zmienić na:
$date_time = date('m/Y'); $unpack = unpack('H*', $date_time); array_shift($unpack);
źródło
Drugi fragment również nie działa i dlatego.
array_shift
jest funkcją modyfikującą, która zmienia swój argument. Dlatego oczekuje, że jego parametr będzie odniesieniem i nie możesz odwołać się do czegoś, co nie jest zmienną. Zobacz wyjaśnienia Rasmusa tutaj: Surowe standardy: Tylko zmienne powinny być przekazywane przez odniesienieźródło
Cóż, w takich oczywistych przypadkach zawsze możesz powiedzieć PHP, aby blokował komunikaty, używając znaku „@” na początku funkcji.
$monthly_index = @array_shift(unpack('H*', date('m/Y')));
Tłumienie wszystkich błędów w ten sposób może nie być jedną z najlepszych praktyk programistycznych , ale w niektórych przypadkach (takich jak ten) jest to przydatne i jest akceptowalne.
W rezultacie jestem pewien, że "administrator systemu" twojego przyjaciela będzie zadowolony z mniej zanieczyszczonego
error.log
.źródło