Niedozwolone przesunięcie łańcucha Ostrzeżenie PHP


193

Po zaktualizowaniu mojej wersji php do 5.4.0-3 pojawia się dziwny błąd PHP.

Mam tę tablicę:

Array
(
    [host] => 127.0.0.1
    [port] => 11211
)

Gdy próbuję uzyskać do niego dostęp w ten sposób, otrzymuję dziwne ostrzeżenia

 print $memcachedConfig['host'];
 print $memcachedConfig['port'];


 Warning: Illegal string offset 'host' in ....
 Warning: Illegal string offset 'port' in ...

Naprawdę nie chcę po prostu edytować pliku php.ini i ponownie ustawiać poziomu błędu.


20
Oczywiście $memcachedConfignie jest to tablica. Showvar_dump($memcachedConfig);
zerkms

1
Oznacza to, że klucze nie istnieją. Sprawdź swoją zmienną var_export($memcachedConfig)tuż przed „print”.
Skrol29

9
Większość osób tęskni za tym, że nie oznacza to dokładnie, że indeks nie istnieje - generuje komunikat „niezdefiniowany indeks”. To inny błąd.
grantwparks

5
stackoverflow.com/a/20271518/2898712 jest poprawną odpowiedzią tutaj.
śr.

19
Uwaga każdy, kto ogląda to pytanie: Prawidłowa odpowiedź na to pytanie nie jest tą zaznaczoną; poprawne jest Kzqai poniżej
Aaron

Odpowiedzi:


37

Spróbuj tego w ten sposób .... Przetestowałem ten kod .... Działa ....

$memcachedConfig = array("host" => "127.0.0.1","port" => "11211");
print_r($memcachedConfig['host']);

1
Znaleziono to. Dzięki za pomoc. var_dump pomógł. Załadowałem tablicę z pliku konfiguracyjnego, który miał taką zawartość strage. array (2) {["host"] => string (9) „127.0.0.1” [„port”] => string (5) „11211”} string (5) „m_prefix” PHP 5.4 teraz $ xx [' host '] rzucił ostrzeżenie poprawnie.
thesonix

Miałem ten sam błąd po include_once($file);. Tablica została poprawnie zbudowana (pokazuje to informacja o debugowaniu), jednak musiała zostać skopiowana ręcznie do innej tablicy, zanim mogła zostać użyta bez komunikatu ostrzegającego o nielegalnym przesunięciu łańcucha PHP.
Franz Holzinger

$ sStartDate = data („Ymd”, strtotime ($ feed ['DTSTART'] ['wartość'])); $ sEndDate = data („Ymd”, strtotime ($ feed ['DTEND'] ['value'])); Jak naprawić ten sam błąd tutaj Ostrzeżenie: Niedozwolone przesunięcie łańcucha
J. Shabu

302

Błąd Illegal string offset 'whatever' in... ogólnie oznacza: próbujesz użyć łańcucha jako pełnej tablicy.

Jest to faktycznie możliwe, ponieważ ciągi znaków mogą być traktowane jako tablice pojedynczych znaków w php. Więc myślisz, że $ var jest tablicą z kluczem, ale to tylko ciąg znaków ze standardowymi klawiszami numerycznymi, na przykład:

$fruit_counts = array('apples'=>2, 'oranges'=>5, 'pears'=>0);
echo $fruit_counts['oranges']; // echoes 5
$fruit_counts = "an unexpected string assignment";
echo $fruit_counts['oranges']; // causes illegal string offset error

Możesz to zobaczyć w akcji tutaj: http://ideone.com/fMhmkR

Dla tych, którzy przychodzą na to pytanie, próbując przełożyć niejasność błędu na coś, co mam z tym zrobić, tak jak ja.


8
Założę się, że można pokazać, że to był powód pierwotnego problemu. Większość komentarzy błędnie zakłada, że ​​„niezdefiniowany indeks” był błędem.
grantwparks

1
Natknąłem się na ten problem w pętli while. Dzięki
David Okwii,

Czasami ten błąd może wystąpić podczas próby złapania niewłaściwego węzła tablicy wielowymiarowej, tj. Przechodzenia „za głęboko”, zamiast tego potrzebny jest element nadrzędny zaznaczenia
zoltar

To prawda, użyłem fetchAll(PDO::FETCH_ASSOC)zamiast tego fetch(PDO::FETCH_ASSOC)i działało idealnie.
MNN

Przypadkowo używałem tego samego $variablename = [];dwa razy, w innej części mojego kodu, $variablename = "test";która spowodowała komunikat o błędzie.
Kai Noack,

77

TL; DR

Próbujesz uzyskać dostęp do stringtablicy, jakby to była tablica, z kluczem, który jest string. stringnie zrozumie tego. W kodzie możemy zobaczyć problem:

"hello"["hello"];
// PHP Warning:  Illegal string offset 'hello' in php shell code on line 1

"hello"[0];
// No errors.

array("hello" => "val")["hello"];
// No errors. This is *probably* what you wanted.

Dogłębnie

Zobaczmy ten błąd:

Ostrzeżenie: niedozwolony przesunięcie ciągu „port” w ...

Co to mówi? Mówi, że próbujemy użyć łańcucha 'port'jako przesunięcia łańcucha. Lubię to:

$a_string = "string";

// This is ok:
echo $a_string[0]; // s
echo $a_string[1]; // t
echo $a_string[2]; // r
// ...

// !! Not good:
echo $a_string['port'];
// !! Warning: Illegal string offset 'port' in ...

Co to powoduje?

Z jakiegoś powodu spodziewałeś się array, ale masz string. Po prostu pomyłka. Może twoja zmienna została zmieniona, może nigdy nie byłaarray , to naprawdę nie jest ważne.

Co można zrobić?

Jeśli wiemy, że powinniśmy mieć array, powinniśmy wykonać podstawowe debugowanie, aby ustalić, dlaczego nie mamy array. Jeśli nie wiemy, czy będziemy mieli, arraylub string, sytuacja stanie się nieco trudniejsza.

Co nam może zrobić, to wszelkiego rodzaju kontroli w celu zapewnienia, że nie mamy Zawiadomienia, ostrzeżenia lub błędy z rzeczy, jak is_arrayi issetalbo array_key_exists:

$a_string = "string";
$an_array = array('port' => 'the_port');

if (is_array($a_string) && isset($a_string['port'])) {
    // No problem, we'll never get here.
    echo $a_string['port'];
}

if (is_array($an_array) && isset($an_array['port'])) {
    // Ok!
    echo $an_array['port']; // the_port
}

if (is_array($an_array) && isset($an_array['unset_key'])) {
    // No problem again, we won't enter.
    echo $an_array['unset_key'];
}


// Similar, but with array_key_exists
if (is_array($an_array) && array_key_exists('port', $an_array)) {
    // Ok!
    echo $an_array['port']; // the_port
}

Istnieją pewne subtelne różnice między isseti array_key_exists. Na przykład, jeśli wartość $array['key']wynosi null, issetzwraca false. array_key_existspo prostu sprawdzi, czy klucz istnieje .


13

Jest tu wiele świetnych odpowiedzi - ale mój problem był nieco prostszy.

Próbowałem uruchomić następujące polecenie:

$x['name']   = $j['name'];

i pojawiał się ten illegal stringbłąd, $x['name']ponieważ najpierw nie zdefiniowałem tablicy. Więc wstawiam następujący wiersz kodu przed próbą przypisania rzeczy do $x[]:

$x = array();

i zadziałało.


1
Myślę, że taka powinna być odpowiedź. Musi być inaczej między 5,4 (i przed 7) a 7
sonnb

7

Trochę za późno na pytanie, ale dla innych, którzy szukają: Ten błąd wystąpił, inicjując z niepoprawną wartością (typ):

$varName = '';
$varName["x"] = "test"; // causes: Illegal string offset

Właściwy sposób to:

 $varName = array();
 $varName["x"] = "test"; // works

Gdzie $ varName jest inicjowany z wartością, która powinna być tablicą, ale może być pusty ciąg, zmuszanie wartość można tego uniknąć, na przykład: $ varName = (array) $ shouldBeArray
markdwhite

4

Począwszy od PHP 5.4 musimy przekazać tę samą wartość typu danych, jakiej oczekuje funkcja. Na przykład:

function testimonial($id); // This function expects $id as an integer

Podczas wywoływania tej funkcji, jeśli podana jest wartość ciągu:

$id = $array['id']; // $id is of string type
testimonial($id); // illegal offset warning

Wygeneruje to ostrzeżenie o nielegalnym przesunięciu z powodu niedopasowania typu danych. Aby rozwiązać ten problem, możesz użyć settype:

$id = settype($array['id'],"integer"); // $id now contains an integer instead of a string
testimonial($id); // now running smoothly

Jak to ma się do tablic ...?
non-descript-użytkownik

2

Przed sprawdzeniem tablicy wykonaj następujące czynności:

if(!is_array($memcachedConfig))
     $memcachedConfig = array();

1

W moim przypadku zmieniam mysql_fetch_assoc na mysql_fetch_array i rozwiązuję. Rozwiązanie zajmuje 3 dni :-( a inne wersje mojego proyecta działają z programem assoc download.


1

W moim przypadku rozwiązałem to, gdy zmieniłem funkcję, która wykonuje zapytanie SQL po: return json_encode($array) następnie:return $array


1

Działa mi to:

Mój testowy kod:

$var2['data'] = array ('a'=>'21','b'=>'32','c'=>'55','d'=>'66','e'=>'77');
foreach($var2 as $result)
{  
    $test = $result['c'];
}
print_r($test);

Wynik: 55

Sprawdźcie chłopaki. Dzięki


1

po prostu użyj

$memcachedConfig = array();

przed

 print $memcachedConfig['host'];
 print $memcachedConfig['port'];


 Warning: Illegal string offset 'host' in ....
 Warning: Illegal string offset 'port' in ....

dzieje się tak, ponieważ nigdy nie definiujesz, co to jest $ memcachedConfig, więc domyślnie są traktowane ciągiem znaków, a nie tablicami.


1

Rozwiązałem ten problem za pomocą funkcji trim (). problem dotyczył miejsca.

więc spróbujmy

$unit_size = []; //please declare the variable type 
$unit_size = exolode("x", $unit_size);
$width  = trim ($unit_size[1] );
$height = trim ($unit_size[2] );

Mam nadzieję, że to Ci pomoże.


0

Wystarczy, że to pomoże komukolwiek, otrzymywałem ten błąd, ponieważ zapomniałem odserializować serializowaną tablicę. To zdecydowanie coś, co sprawdziłbym, czy dotyczy twojej sprawy.


0

Jest stary, ale na wypadek, gdyby ktoś mógł z tego skorzystać. Ten błąd pojawi się również, jeśli tablica jest pusta.

W moim przypadku miałem:

$buyers_array = array();
$buyers_array = tep_get_buyers_info($this_buyer_id); // returns an array
...
echo $buyers_array['firstname'] . ' ' . $buyers_array['lastname']; 

który zmieniłem na:

$buyers_array = array();
$buyers_array = tep_get_buyers_info($this_buyer_id); // returns an array
...
if(is_array($buyers_array)) {
   echo $buyers_array['firstname'] . ' ' . $buyers_array['lastname']; 
} else {
   echo 'Buyers id ' . $this_buyer_id . ' not found';
}

0

myślę, że jedynym powodem tego komunikatu jest to, że tablica docelowa jest w rzeczywistości tablicą podobną do łańcucha itp. (JSON -> {„host”: „127.0.0.1”}))


0

Dla PHP

//Setup Array like so
$memcachedConfig = array(
  "host" => "127.0.0.1",
  "port" => "11211"
);

//Always a good practice to check if empty

if(isset($memcachedConfig['host']) && isset($memcachedConfig['port'])){

    //Some codes

    print_r ($memcachedConfig['host']);
    print_r ($memcachedConfig['port']);

}

Upewnij się tylko, że zwracana wartość nie jest pusta. Ten przykład dotyczy PHP, więc dowiedz się, jak sprawdzić, czy tablica jest pusta w innych językach.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.