json_encode NULL döndürüyor mu?


119

Bazı nedenlerden dolayı "açıklama" öğesi NULLaşağıdaki kodla döner :

<?php
include('db.php');

$result = mysql_query('SELECT * FROM `staff` ORDER BY `id` DESC LIMIT 2') or die(mysql_error());
$rows = array();
while($row = mysql_fetch_assoc($result)){
    $rows[] = $row;
}

echo json_encode($rows);
?>

İşte veritabanım için şema:

CREATE TABLE `staff` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` longtext COLLATE utf8_unicode_ci,
  `description` longtext COLLATE utf8_unicode_ci,
  `icon` longtext COLLATE utf8_unicode_ci,
  `date` longtext COLLATE utf8_unicode_ci,
  `company` longtext COLLATE utf8_unicode_ci,
  `companyurl` longtext COLLATE utf8_unicode_ci,
  `appurl` longtext COLLATE utf8_unicode_ci,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

İşte sayfada yankılanan şey:

[{"id":"4","name":"Noter 2","description":null,"icon":"http:\/\/images.apple.com\/webapps\/productivity\/images\/noter2_20091223182720-thumb.jpg","date":"1262032317","company":"dBelement, LLC","companyurl":"http:\/\/dbelement.com\/","appurl":"http:\/\/noter2.dbelement.com"},{"id":"3","name":"Noter 2","description":null,"icon":"http:\/\/images.apple.com\/webapps\/productivity\/images\/noter2_20091223182720-thumb.jpg","date":"1262032317","company":"dBelement, LLC","companyurl":"http:\/\/dbelement.com\/","appurl":"http:\/\/noter2.dbelement.com"}]

Herhangi bir fikir?


Öncelikle dizi anahtarlarını tırnak içine alalım.
Joost

"Personel" tablonuzun şeması hakkında bilgi verebilir misiniz? Açıklama adında bir sütun var mı?
mopoke

$r['description']for () ifadesinin dışında bir yankı yaparsam bu alanların tümü yankılanır.
tarnfeld

Ya da belki $ r ['açıklama'] 'dan bazı örnek içerik yardımcı olabilir. Bu hangi veri türü?
mopoke

veritabanı shema'nın ekran görüntüsünü alabilir misin? ;-)
streetparade

Yanıtlar:


256

Bahse girerim utf8 olmayan kodlamada veri alıyorsunuz: sorgunuzun mysql_query('SET CHARACTER SET utf8')önüne koymayı deneyin SELECT.


5
merhaba, bu cevap hayatımı kurtardı, teşekkür ederim. Ben de burada aynı sorunu yaşıyordum. "Validação de Formulários" gibi utf8 olmayan karakterlere sahip değerlerim vardı. Bu sorunun artık biraz eski olduğunu biliyorum, ama bu internetin muhteşemliği !!
fabio

7
mysql_set_charset, PHP 5.2.3'ten beri güvenlik nedeniyle daha iyidir. Ayrıntılar için php.net/manual/en/function.mysql-set-charset.php bakın.
masakielastic

3
Çünkü UTF8 web'deki ortak dildir. API'yi ek parametreler ve ek yük ile karıştırmak yerine, PHP (kesinlikle) en yaygın kodlamayı kullanır ve alışılmadık (veya sizin durumunuzda olduğu gibi neredeyse ölü) bir kodlama kullanıyorsanız size dönüşüm yükünü bırakır.
ntd

1
Bunu yapmanın önerilen yolu şimdi değişti. Bu yanıtı bir bağlantı içerecek şekilde düzenlemeye çalıştım ancak reddedildim. Doğru yol, aşağıdaki cevabımda.
bejs

1
@VeeK alanlarınızın UTF-8'de saklanması yeterli değildir: sunucunuzu istemcilere UTF-8'de yanıt verecek şekilde yapılandırmalısınız . AFAIK stok mysql ve mariadb latin1 kullanır.
ntd

118

En az PHP 5.5'iniz varsa, json_last_error_msg () kullanabilirsiniz. , sorunu açıklayan bir dizge döndürecek .

5.5'iniz yoksa, ancak 5.3 ve üzerindeyseniz, json_last_error () kullanabilirsiniz. , sorunun ne olduğunu görmek .

Fonksiyonun belgelerinde problemi tanımlamak için kullanabileceğiniz bir tamsayı döndürecektir . Şu anda (2012.01.19), tanımlayıcılar:

0 = JSON_ERROR_NONE
1 = JSON_ERROR_DEPTH
2 = JSON_ERROR_STATE_MISMATCH
3 = JSON_ERROR_CTRL_CHAR
4 = JSON_ERROR_SYNTAX
5 = JSON_ERROR_UTF8

Bunlar gelecekteki sürümlerde değişebilir, bu nedenle kılavuza başvurmak daha iyidir.

5.3'ün altındaysanız, şansınız kalmaz, hatanın ne olduğunu sormanın bir yolu yoktur.


18

ntd'nin yanıtlayıcısı sorunumu çözmedi. Aynı durumda olanlar için, sonunda bu hatayı nasıl ele aldım: Sonuçlarınızın her birine sadece utf8_encode.

while($row = mysql_fetch_assoc($result)){
    $rows[] = array_map('utf8_encode', $row);
}

Umarım yardımcı olur!


Benim de kodlama sorunlarım vardı. w / karışık kodlama. bulduğum çözüm: stackoverflow.com/a/3521396/776345
Paschalis

9

Birkaç gün önce 1 masa ile AYNI problemim var.

Önce şunu deneyin:

echo json_encode($rows);
echo json_last_error();  // returns 5 ?

Son satır 5 döndürürse, sorun verilerinizle ilgilidir . Biliyorum, tablolarınız UTF-8'de ama veri girilmemiş . Örneğin, girdi txt dosyasındaydı, ancak aptal kodlama ile Win makinesinde oluşturuldu (benim durumumda Win-1250 = CP1250) ve bu veriler DB'ye girildi.

Çözüm? Yeni verileri arayın (excel, web sayfası), kaynak txt dosyasını PSPad (veya başka herhangi bir şekilde) aracılığıyla düzenleyin , kodlamayı UTF-8 olarak değiştirin , tüm satırları silin ve şimdi orijinalden verileri yerleştirin. Kayıt etmek. DB'ye girin .

Ayrıca kodlamayı sadece utf-8 olarak değiştirebilir ve ardından tüm satırları manuel olarak değiştirebilirsiniz (özel karakterlerle sütun verin - desc, ...). Köleler için iyi ...


veya sorunu görmek için JSON_PARTIAL_OUTPUT_ON_ERRORseçeneği kullanın (örneğin, UTF8 ile alan boş olacaktır).
Peter Krauss

6

Json_encode'da utf8 kodlu dizeyi iletmelisiniz. Aşağıdaki gibi kullanabilir utf8_encodeve array_map()çalışabilirsiniz:

<?php
    $encoded_rows = array_map('utf8_encode', $rows);
    echo json_encode($encoded_rows);
?>

4

Ahhh !!! Bu çok yanlış görünüyor, kafamı acıtıyor. Bunun gibi daha fazlasını dene ...

<?php
include('db.php');

$result = mysql_query('SELECT `id`, `name`, `description`, `icon` FROM `staff` ORDER BY `id` DESC LIMIT 20') or die(mysql_error());
$rows = array();
while($row = mysql_fetch_assoc($result)){
    $rows[] = $row;
}

echo json_encode($rows);
?>
  • Yineleme zaman üzerinde mysql_num_rowskullanmanız gereken <değil <=. Her döngüyü yeniden saymak yerine bu değeri önbelleğe almalısınız (bir değişkene kaydetmelisiniz). Kaputun altında ne yaptığını kim bilebilir ... (verimli olabilir, gerçekten emin değilim)
  • Her bir değeri açıkça bu şekilde kopyalamanıza gerek yok ... sadece bunu kendiniz için zorlaştırıyorsunuz. Sorgu, orada listelediğinizden daha fazla değer döndürüyorsa, yalnızca SQL'inizde olmasını istediklerinizi listeleyin.
  • mysql_fetch_arrayhem by hem de by keyile değerleri döndürür int. Endeksleri kullanmıyorsun, bu yüzden onları getirme.

Bu gerçekten bir sorunsa json_encode, döngünün gövdesini aşağıdaki gibi bir şeyle değiştirmeyi önerebilir miyim?

$rows[] = array_map('htmlentities',$row);

Perhpalar, bir şeyleri karıştıran bazı özel karakterler var ...


[{"id": "4", "name": "Noter 2", "description": null, "icon": "http: \ / \ / images.apple.com \ / webapps \ / generator \ / images \ /noter2_20091223182720-thumb.jpg "," tarih ":" 1262032317 "," şirket ":" dBelement, LLC "," companyurl ":" http: \ / \ / dbelement.com \ / "," appurl ":" http: \ / \ / noter2.dbelement.com "}, {" id ":" 3 "," name ":" Noter 2 "," description ": null," icon ":" http: \ / \ / images .apple.com \ / webapps \ / generator \ / images \ /noter2_20091223182720-thumb.jpg "," tarih ":" 1262032317 "," şirket ":" dBelement, LLC "," şirketurl ":" http: \ / \ /dbelement.com\/","appurl":"http:\/\/noter2.dbelement.com"
tarnfeld

@tarnfield: Peki istediğin bu mu, istemiyor musun? Oh .. orada bazı ek bilgiler var ... burada ... bunu senin için düzeltmeme izin ver.
mpen

evet "açıklama" dönernull
tarnfeld

Açıklama dönüyor ise nullo zaman muhtemelen olduğunu null . echo $row['description'].'<br/>';Bu döngüde deneyin ve ne yazdığını görün.
mpen

1
merhaba, bu cevap hayatımı kurtardı, teşekkür ederim. Ben de burada aynı sorunu yaşıyordum. "Validação de Formulários" gibi utf8 olmayan karakterlere sahip değerlerim vardı. Bu sorunun artık biraz eski olduğunu biliyorum, ama bu internetin muhteşemliği !!
fabio


3

PDO kullanan herkes için çözüm ntd'nin cevabına benzer .

Gönderen PHP PDO :: __ construct sayfası , kullanıcıdan gelen bir yorum olarak canlı nokta com Kiipa :

UTF-8 karakter kümesini almak için bunu DSN'de belirtebilirsiniz.

$ link = yeni PDO ("mysql: host = localhost; dbname = DB; charset = UTF8 ");


0

Benim için, json_encode'un bir varlığın boş kodlamasını döndürmesi sorunu, jsonSerialize uygulamamın ilgili varlıklar için tüm nesneleri getirmesiydi; Json serileştirilecek nesneyle ilişkili birden fazla varlık olduğunda ilgili / ilişkili varlığın kimliğini getirdiğimden ve -> toArray () olarak adlandırdığımdan emin olarak sorunu çözdüm. Dikkat edin, implements JsonSerializablevarlıklar üzerinde birinin olduğu durumlardan bahsediyorum .


-4

Aynı sorunu yaşadım ve çözüm yerine kendi işlevimi kullanmaktı json_encode()

echo '["' . implode('","', $row) . '"]';
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.