1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關(guān)咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務(wù)時(shí)間:8:30-17:00
      你可能遇到了下面的問(wèn)題
      關(guān)閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
      PHP中與JSON相關(guān)的函數(shù)有哪些

      這篇文章將為大家詳細(xì)講解有關(guān)PHP中與JSON相關(guān)的函數(shù)有哪些,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

      成都創(chuàng)新互聯(lián)公司專注于獨(dú)山網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠(chéng)為您提供獨(dú)山營(yíng)銷型網(wǎng)站建設(shè),獨(dú)山網(wǎng)站制作、獨(dú)山網(wǎng)頁(yè)設(shè)計(jì)、獨(dú)山網(wǎng)站官網(wǎng)定制、微信平臺(tái)小程序開(kāi)發(fā)服務(wù),打造獨(dú)山網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供獨(dú)山網(wǎng)站排名全網(wǎng)營(yíng)銷落地服務(wù)。

      在我們當(dāng)年剛剛上班的那個(gè)年代,還全是 XML 的天下,但現(xiàn)在 JSON 數(shù)據(jù)格式已經(jīng)是各種應(yīng)用傳輸?shù)氖聦?shí)標(biāo)準(zhǔn)了。最近幾年開(kāi)始學(xué)習(xí)編程開(kāi)發(fā)的同學(xué)可能都完全沒(méi)有接觸過(guò)使用 XML 來(lái)進(jìn)行數(shù)據(jù)傳輸。當(dāng)然,時(shí)代是一直在進(jìn)步的,JSON 相比 XML 來(lái)說(shuō),更加地方便快捷,可讀性更高。但其實(shí)從語(yǔ)義的角度來(lái)說(shuō),XML 的表現(xiàn)形式更強(qiáng)。

      話不多說(shuō),在 PHP 中操作 JSON 其實(shí)非常簡(jiǎn)單,大家最常用的無(wú)非也就是 json_encode() 和 json_decode() 這兩個(gè)函數(shù)。它們有一些需要注意的地方,也有一些好玩的地方。

      JSON 編碼

      首先,我們準(zhǔn)備一個(gè)數(shù)組,用于我們后面編碼的操作。

      $data = [
          'id' => 1,
          'name' => '測(cè)試情況',
          'cat' => [
              '學(xué)生 & "在職"',
          ],
          'number' => "123123123",
          'edu' => [
              [
                  'name' => '中學(xué)',
                  'date' => '2015-2018',
              ],
              [
                  'name' => '大學(xué)',
                  'date' => '2018-2022',
              ],
          ],
      ];

      非常簡(jiǎn)單地?cái)?shù)組,其實(shí)也沒(méi)有什么特別的東西,只是有數(shù)據(jù)的嵌套,有一些中文和特殊符號(hào)而已。對(duì)于普通的 JSON 編碼來(lái)說(shuō),直接使用 json_encode() 就可以了。

      $json1 = json_encode($data);
      var_dump($json1);
      // string(215) "{"id":1,"name":"\u6d4b\u8bd5\u60c5\u51b5","cat":["\u5b66\u751f & \"\u5728\u804c\""],"number":"123123123","edu":[{"name":"\u4e2d\u5b66<\/b>","date":"2015-2018"},{"name":"\u5927\u5b66<\/b>","date":"2018-2022"}]}"

      中文處理

      上面編碼后的 JSON 數(shù)據(jù)發(fā)現(xiàn)了什么問(wèn)題沒(méi)?沒(méi)錯(cuò),相信不少人一眼就會(huì)看出,中文字符全被轉(zhuǎn)換成了 \uxxxx 這種格式。這其實(shí)是在默認(rèn)情況下,json_encode() 函數(shù)都會(huì)將這些多字節(jié)字符轉(zhuǎn)換成 Unicode 格式的內(nèi)容。我們直接在 json_encode() 后面增加一個(gè)常量參數(shù)就可以解決這個(gè)問(wèn)題,讓中文字符正常地顯示出來(lái)。

      $json1 = json_encode($data, JSON_UNESCAPED_UNICODE);
      var_dump($json1);
      // string(179) "{"id":1,"name":"測(cè)試情況","cat":["學(xué)生 & \"在職\""],"number":"123123123","edu":[{"name":"中學(xué)<\/b>","date":"2015-2018"},{"name":"大學(xué)<\/b>","date":"2018-2022"}]}"

      當(dāng)然,只是這樣就太沒(méi)意思了。因?yàn)槲以?jīng)在面試的時(shí)候就有一位面試官問(wèn)過(guò)我,如果解決這種問(wèn)題,而且不用這個(gè)常量參數(shù)。大家可以先不看下面的代碼,思考一下自己有什么解決方案嗎?

      function t($data)
      {
          foreach ($data as $k => $d) {
              if (is_object($d)) {
                  $d = (array) $d;
              }
              if (is_array($d)) {
                  $data[$k] = t($d);
              } else {
                  $data[$k] = urlencode($d);
              }
          }
          return $data;
      }
      $newData = t($data);
      
      $json1 = json_encode($newData);
      var_dump(urldecode($json1));
      // string(177) "{"id":"1","name":"測(cè)試情況","cat":["學(xué)生 & "在職""],"number":"123123123","edu":[{"name":"中學(xué)","date":"2015-2018"},{"name":"大學(xué)","date":"2018-2022"}]}"

      其實(shí)就是一個(gè)很簡(jiǎn)單地解決方案,遞歸地將數(shù)據(jù)中所有字段內(nèi)容轉(zhuǎn)換成 urlencode() 編碼,然后再使用 json_encode() 編碼,完成之后再使用 urldecode() 反解出來(lái)。是不是有點(diǎn)意思?其實(shí)這是不少老程序員的一個(gè)小技巧,因?yàn)?JSON_UNESCAPED_UNICODE 這個(gè)常量是在 PHP5.4 之后才有的,之前的話如果想讓編碼后的數(shù)據(jù)直接顯示中文,就只能這樣操作了。

      當(dāng)然,現(xiàn)在已經(jīng)是 PHP8 時(shí)代了,早就已經(jīng)不需要這么麻煩地操作了,不過(guò)也不能排除有些面試館仗著自己是老碼農(nóng)故意出些這樣的題目。大家了解下,知道有這么回事就可以了,畢竟在實(shí)際的項(xiàng)目開(kāi)發(fā)中,使用 PHP5.4 以下版本的系統(tǒng)可能還真是非常少了(這樣的公司不去也罷,技術(shù)更新得太慢了)。

      其它參數(shù)

      除了 JSON_UNESCAPED_UNICODE 之外,我們還有許多的常量參數(shù)可以使用,而且這個(gè)參數(shù)是可以并行操作的,也就是可以多個(gè)常量參數(shù)共同生效。

      $json1 = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP | JSON_NUMERIC_CHECK | JSON_HEX_QUOT);
      var_dump($json1);
      // string(230) "{"id":1,"name":"測(cè)試情況","cat":["學(xué)生 \u0026 \u0022在職\u0022"],"number":123123123,"edu":[{"name":"\u003Cb\u003E中學(xué)\u003C\/b\u003E","date":"2015-2018"},{"name":"\u003Cb\u003E大學(xué)\u003C\/b\u003E","date":"2018-2022"}]}"

      這一堆參數(shù)其實(shí)是針對(duì)的我們數(shù)據(jù)中的一些特殊符號(hào),比如說(shuō) & 符、<> HTML 標(biāo)簽等。當(dāng)然,還有一些常量參數(shù)沒(méi)有全部展示出來(lái),大家可以自己查閱官方手冊(cè)中的說(shuō)明。

      另外,json_encode() 還有第三個(gè)參數(shù),代表的是迭代的層級(jí)。比如我們上面的這個(gè)數(shù)據(jù)是多維數(shù)組,它有三層,所以我們至少要給到 3 才能正常地解析。下面代碼我們只是給了一個(gè) 1 ,所以返回的內(nèi)容就是 false 。也就是無(wú)法編碼成功。默認(rèn)情況下,這個(gè)參數(shù)的值是 512 。

      var_dump(json_encode($data, JSON_UNESCAPED_UNICODE, 1)); // bool(false)

      對(duì)象及格式處理

      默認(rèn)情況下,json_encode() 會(huì)根據(jù)數(shù)據(jù)的類型進(jìn)行編碼,所以如果是數(shù)組的話,那么它編碼之后的內(nèi)容就是 JSON 的數(shù)組格式,這時(shí)我們也可以添加一個(gè) JSON_FORCE_OBJECT ,讓它將一個(gè)數(shù)組以對(duì)象的形式進(jìn)行編碼。

      $data = [];
      var_dump(json_encode($data)); // string(2) "[]"
      var_dump(json_encode($data, JSON_FORCE_OBJECT)); // string(2) "{}"

      之前在講數(shù)學(xué)相關(guān)函數(shù)的時(shí)候我們學(xué)習(xí)過(guò),如果數(shù)據(jù)中有 NAN 這種數(shù)據(jù)的話,json_encode() 是無(wú)法編碼的,其實(shí)我們可以添加一個(gè) JSON_PARTIAL_OUTPUT_ON_ERROR ,對(duì)一些不可編碼的值進(jìn)行替換。下面的代碼中,我們就可以使用它讓 NAN 替換成 0 。

      $data = NAN;
      var_dump(json_encode($data)); // bool(false)
      var_dump(json_encode($data, JSON_PARTIAL_OUTPUT_ON_ERROR)); // 0

      對(duì)象編碼的屬性問(wèn)題

      對(duì)于對(duì)象來(lái)說(shuō),JSON 編碼后的內(nèi)容就和序列化一樣,只會(huì)有對(duì)象的屬性而不會(huì)有方法。畢竟 JSON 最大的用處就是用于數(shù)據(jù)傳輸?shù)模椒▽?duì)于數(shù)據(jù)傳輸來(lái)說(shuō)沒(méi)有什么實(shí)際的作用。而屬性也會(huì)根據(jù)它的封裝情況有所不同,只會(huì)編碼公共的,也就是 public 的屬性。

      $data = new class
      {
          private $a = 1;
          protected $b = 2;
          public $c = 3;
      
          public function x(){
              
          }
      };
      var_dump(json_encode($data)); // string(7) "{"c":3}"

      從這段測(cè)試代碼中可以看出,protected 、 private 屬性以及那個(gè)方法都不會(huì)被編碼。

      JSON 解碼

      對(duì)于 JSON 解碼來(lái)說(shuō),其實(shí)更簡(jiǎn)單一些,因?yàn)?json_decode() 的常量參數(shù)沒(méi)有那么多。

      var_dump(json_decode($json1));
      // object(stdClass)#1 (5) {
      //     ["id"]=>
      //     int(1)
      //     ["name"]=>
      //     string(12) "測(cè)試情況"
      //     ["cat"]=>
      // ……
      // ……
      
      var_dump(json_decode($json1, true));
      // array(5) {
      //     ["id"]=>
      //     int(1)
      //     ["name"]=>
      //     string(12) "測(cè)試情況"
      //     ["cat"]=>
      // ……
      // ……

      首先還是看下它的第二個(gè)參數(shù)。這個(gè)參數(shù)的作用其實(shí)從代碼中就可以看出來(lái),如果不填這個(gè)參數(shù),也就是默認(rèn)情況下它的值是 false ,那么解碼出來(lái)的數(shù)據(jù)是對(duì)象格式的。而我們將這具參數(shù)設(shè)置為 true 的話,那么解碼后的結(jié)果就會(huì)是數(shù)組格式的。這個(gè)也是大家非常常用的功能,就不多做解釋了。

      var_dump(json_decode('{"a":1321231231231231231231231231231231231231231231231231231231231231231231233}', true));
      // array(1) {
      //     ["a"]=>
      //     float(1.3212312312312E+72)
      //   }
      
      var_dump(json_decode('{"a":1321231231231231231231231231231231231231231231231231231231231231231231233}', true, 512, JSON_BIGINT_AS_STRING));
      // array(1) {
      //     ["a"]=>
      //     string(73) "1321231231231231231231231231231231231231231231231231231231231231231231233"
      //   }

      對(duì)于這種非常長(zhǎng)的數(shù)字格式的數(shù)據(jù)來(lái)說(shuō),如果直接 json_decode() 解碼的話,它會(huì)直接轉(zhuǎn)換成 科學(xué)計(jì)數(shù)法 。我們可以直接使用一個(gè) JSON_BIGINT_AS_STRING 常量參數(shù),將這種數(shù)據(jù)在解碼的時(shí)候直接轉(zhuǎn)換成字符串,其實(shí)也就是保留了數(shù)據(jù)的原始樣貌。注意,這里 json_decode() 函數(shù)的參數(shù)因?yàn)橛心莻€(gè)轉(zhuǎn)換對(duì)象為數(shù)組的參數(shù)存在,所以它有四個(gè)參數(shù),第三個(gè)參數(shù)是迭代深度,第四個(gè)就是定義這些格式化常量值的。而且它和 json_encode() 是反過(guò)來(lái)的,迭代深度參數(shù)在前,格式常量參數(shù)在后面,這里一定要注意哦!

      如果數(shù)據(jù)是錯(cuò)誤的,那么 json_decode() 會(huì)返回 NULL 。

      var_dump(json_decode("", true)); // NULL
      var_dump(json_decode("{a:1}", true)); // NULL

      錯(cuò)誤處理

      上面兩段代碼中我們都演示了如果編碼或解碼的數(shù)據(jù)有問(wèn)題會(huì)出現(xiàn)什么情況,比如 json_encode() 會(huì)返回 false ,json_decode() 會(huì)返回 NULL 。但是具體的原因呢?

      $data = NAN;
      var_dump(json_encode($data)); // bool(false)
      var_dump(json_last_error()); // int(7)
      var_dump(json_last_error_msg()); // string(34) "Inf and NaN cannot be JSON encoded"

      沒(méi)錯(cuò),json_last_error() 和 json_last_error_msg() 就是返回 JSON 操作時(shí)的錯(cuò)誤信息的。也就是說(shuō),json_encode() 和 json_decode() 在正常情況下是不會(huì)報(bào)錯(cuò)的,我們?nèi)绻@得錯(cuò)誤信息,就得使用這兩個(gè)函數(shù)來(lái)獲取。這一點(diǎn)也是不少新手小同學(xué)沒(méi)有注意過(guò)的地方,沒(méi)錯(cuò)誤信息,不拋出異常問(wèn)題對(duì)我們的開(kāi)發(fā)調(diào)試其實(shí)是非常不友好的。因?yàn)楹芸赡苷伊税胩於疾恢绬?wèn)題出在哪里。

      在 PHP7.3 之后,新增加了一個(gè)常量參數(shù),可以讓我們的 json_encode() 和 json_decode() 在編解碼錯(cuò)誤的時(shí)候拋出異常,這樣我們就可以快速地定位問(wèn)題了,現(xiàn)在如果大家的系統(tǒng)運(yùn)行環(huán)境是 PHP7.3 以上的話,非常推薦使用這個(gè)常量參數(shù)讓系統(tǒng)來(lái)拋出異常。

      // php7.3
      var_dump(json_encode($data, JSON_THROW_ON_ERROR));
      // Fatal error: Uncaught JsonException: Inf and NaN cannot be JSON encoded
      
      var_dump(json_decode('', true, 512, JSON_THROW_ON_ERROR));
      // PHP Fatal error:  Uncaught JsonException: Syntax error

      JSON_THROW_ON_ERROR 是對(duì) json_encode() 和 json_decode() 都起效的。同樣,只要設(shè)定了這個(gè)常量參數(shù),我們就可以使用 try...catch 來(lái)進(jìn)行捕獲了。

      try {
          var_dump(json_encode($data, JSON_THROW_ON_ERROR));
      } catch (JsonException $e) {
          var_dump($e->getMessage()); // string(34) "Inf and NaN cannot be JSON encoded"
      }

      JSON 序列化接口

      在之前的文章中,我們學(xué)習(xí)過(guò) 使用Serializable接口來(lái)自定義PHP中類的序列化 。也就是說(shuō),通過(guò) Serializable 接口我們可以自定義序列化的格式內(nèi)容。而對(duì)于 JSON 來(lái)說(shuō),同樣也提供了一個(gè) JsonSerializable 接口來(lái)實(shí)現(xiàn)我自定義 JSON 編碼時(shí)的對(duì)象格式內(nèi)容。

      class jsontest implements JsonSerializable
      {
          public function __construct($value)
          {$this->value = $value;}
          public function jsonSerialize()
          {return $this->value;}
      }
      
      print "Null -> " . json_encode(new jsontest(null)) . "\n";
      print "Array -> " . json_encode(new jsontest(array(1, 2, 3))) . "\n";
      print "Assoc. -> " . json_encode(new jsontest(array('a' => 1, 'b' => 3, 'c' => 4))) . "\n";
      print "Int -> " . json_encode(new jsontest(5)) . "\n";
      print "String -> " . json_encode(new jsontest('Hello, World!')) . "\n";
      print "Object -> " . json_encode(new jsontest((object) array('a' => 1, 'b' => 3, 'c' => 4))) . "\n";
      // Null -> null
      // Array -> [1,2,3]
      // Assoc. -> {"a":1,"b":3,"c":4}
      // Int -> 5
      // String -> "Hello, World!"
      // Object -> {"a":1,"b":3,"c":4}

      這是一個(gè)小的示例,只需要實(shí)現(xiàn) JsonSerializable 接口中的 jsonSerialize() 方法并返回內(nèi)容就可以實(shí)現(xiàn)這個(gè) jsontest 對(duì)象的 JSON 編碼格式的指定。這里我們只是簡(jiǎn)單地返回了數(shù)據(jù)的內(nèi)容,其實(shí)和普通的 json_encode() 沒(méi)什么太大的區(qū)別。下面我們通過(guò)一個(gè)復(fù)雜的例子看一下。

      class Student implements JsonSerializable
      {
          private $id;
          private $name;
          private $cat;
          private $number;
          private $edu;
          public function __construct($id, $name, $cat = null, $number = null, $edu = null)
          {
              $this->id = $id;
              $this->name = $name;
              $this->cat = $cat;
              $this->number = $number;
              $this->edu = $edu;
      
          }
          public function jsonSerialize()
          {
              if (!$cat) {
                  $this->cat = ['學(xué)生'];
              }
              if (!$edu) {
                  $this->edu = new stdClass;
              }
              $this->number = '學(xué)號(hào):' . (!$number ? mt_rand() : $number);
              if ($this->id == 2) {
                  return [
                      $this->id,
                      $this->name,
                      $this->cat,
                      $this->number,
                      $this->edu,
                  ];
              }
              return [
                  'id' => $this->id,
                  'name' => $this->name,
                  'cat' => $this->cat,
                  'number' => $this->number,
                  'edu' => $this->edu,
              ];
          }
      }
      
      var_dump(json_encode(new Student(1, '測(cè)試一'), JSON_UNESCAPED_UNICODE));
      // string(82) "{"id":1,"name":"測(cè)試一","cat":["學(xué)生"],"number":"學(xué)號(hào):14017495","edu":{}}"
      
      var_dump(json_encode([new Student(1, '測(cè)試一'), new Student(2, '測(cè)試二')], JSON_UNESCAPED_UNICODE));
      // string(137) "[{"id":1,"name":"測(cè)試一","cat":["學(xué)生"],"number":"學(xué)號(hào):1713936069","edu":{}},[2,"測(cè)試二",["學(xué)生"],"學(xué)號(hào):499173036",{}]]"

      在這個(gè)例子中,我們?cè)?jsonSerialize() 做了一些操作。如果數(shù)據(jù)沒(méi)有傳值,比如為 null 的情況下就給一個(gè)默認(rèn)值。然后在 id 為 2 的情況下返回一個(gè)普通數(shù)組。大家可以看到最后一段注釋中的第二條數(shù)據(jù)的格式。

      這個(gè)接口是不是很有意思,相信大家可能對(duì)上面的 json_encode() 和 json_decode() 非常熟悉了,但這個(gè)接口估計(jì)不少人真的是沒(méi)接觸過(guò),是不是非常有意思。

      關(guān)于“PHP中與JSON相關(guān)的函數(shù)有哪些”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。


      名稱欄目:PHP中與JSON相關(guān)的函數(shù)有哪些
      文章源于:http://www.ef60e0e.cn/article/gegips.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
          1. <ul id="0c1fb"></ul>

            <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
            <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

            水富县| 金川县| 孟津县| 太和县| 丰原市| 星座| 寿宁县| 辽源市| 洛隆县| 门头沟区| 珠海市| 乐至县| 平和县| 林口县| 清镇市| 栾城县| 汶上县| 灵石县| 葫芦岛市| 常熟市| 南京市| 临海市| 仙游县| 腾冲县| 玉田县| 江山市| 阿克苏市| 什邡市| 远安县| 台中县| 巴塘县| 邓州市| 固镇县| 和顺县| 长顺县| 云龙县| 马公市| 招远市| 哈巴河县| 刚察县| 阿城市|