PHP에서 JSON을 작동하는 방법은 무엇입니까? 이 기사에서는 PHP의 JSON 관련 기능에 대해 자세히 알아보고 이러한 기능을 사용할 때 주의해야 할 사항을 소개합니다. 도움이 되길 바랍니다.
우리가 처음 일을 시작하던 시대에는 여전히 XML이 세상을 지배했지만 이제는 JSON 데이터 형식이 다양한 애플리케이션 전송의 사실상 표준이 되었습니다. 최근 몇 년 동안 프로그래밍과 개발을 배우기 시작한 학생들은 데이터 전송에 XML을 사용하는 방법을 접해 본 적이 없을 것입니다. 물론, 시대는 지속적으로 발전하고 있습니다. XML에 비해 JSON은 더 편리하고 빠르며 읽기 쉽습니다. 그러나 실제로 의미론적 관점에서 보면 XML이 더 표현력이 뛰어납니다.
더 이상 고민하지 않고, PHP에서 JSON을 작동하는 것은 실제로 가장 일반적으로 사용되는 두 가지 함수는 json_encode()와 json_decode()입니다. 조심해야 할 것도 있고, 즐길 것도 있습니다. 오늘은 이에 대해 심도있게 공부해 보겠습니다.
JSON 인코딩
먼저, 후속 인코딩 작업을 위한 배열을 준비합니다.
$data = [ 'id' => 1, 'name' => '测试情况', 'cat' => [ '学生 & "在职"', ], 'number' => "123123123", 'edu' => [ [ 'name' => '<b>中学</b>', 'date' => '2015-2018', ], [ 'name' => '<b>大学</b>', 'date' => '2018-2022', ], ], ];
매우 간단한 배열입니다. 사실 특별한 것은 없습니다. 단지 데이터와 일부 중국어 및 특수 기호가 중첩되어 있을 뿐입니다. 일반적인 JSON 인코딩의 경우 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":"<b>\u4e2d\u5b66<\/b>","date":"2015-2018"},{"name":"<b>\u5927\u5b66<\/b>","date":"2018-2022"}]}"
중국어 처리
위의 인코딩된 JSON 데이터에서 문제를 발견하셨나요? 그렇죠, 많은 분들이 한눈에 한자를 모두 uxxxx 형식으로 변환한 것을 보실 수 있을 거라 믿습니다. 이는 실제로 기본적으로 json_encode() 함수가 이러한 멀티바이트 문자를 유니코드 형식 콘텐츠로 변환합니다. json_encode() 바로 뒤에 상수 매개변수를 추가하면 한자가 정상적으로 표시될 수 있도록 하여 이 문제를 해결할 수 있습니다.
$json1 = json_encode($data, JSON_UNESCAPED_UNICODE); var_dump($json1); // string(179) "{"id":1,"name":"测试情况","cat":["学生 & \"在职\""],"number":"123123123","edu":[{"name":"<b>中学<\/b>","date":"2015-2018"},{"name":"<b>大学<\/b>","date":"2018-2022"}]}"
그렇게 하면 당연히 지루할 텐데. 한번은 면접관이 인터뷰 중에 나에게 이 상수 매개변수를 사용하지 않고 이 문제를 해결할 수 있는지 물었기 때문입니다. 아래 코드를 보지 말고 자신만의 솔루션을 생각해 보세요.
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":"测试情况","cat":["学生 & "在职""],"number":"123123123","edu":[{"name":"<b>中学</b>","date":"2015-2018"},{"name":"<b>大学</b>","date":"2018-2022"}]}"
는 실제로 매우 간단한 솔루션입니다. 데이터의 모든 필드 내용을 urlencode() 인코딩으로 재귀적으로 변환한 다음 json_encode()를 사용하여 인코딩하고, 완료 후 urldecode()를 사용하여 디코딩합니다. 흥미롭지 않나요? 실제로 JSON_UNESCAPED_UNICODE 상수는 PHP5.4 이후에만 사용할 수 있었기 때문에 이는 많은 오래된 프로그래머들의 작은 트릭이었습니다. 이전에는 인코딩된 데이터를 중국어로 직접 표시하려면 이 방법만 사용할 수 있었습니다.
물론 지금은 PHP8 시대라 그런 번거로운 작업은 필요 없습니다. 하지만 일부 면접관에서는 경험이 풍부한 코더이기 때문에 일부러 그런 질문을 하는 경우도 배제할 수 없습니다. 사실은 이것만 알아도 충분하다는 점 여러분 이해해 주시기 바랍니다. 결국 실제 프로젝트 개발에서는 PHP5.4 이하 버전을 사용하는 시스템이 거의 없을 수 있습니다. (그런 회사에 가지 않아도 괜찮습니다. 기술 업데이트는 너무 느림) .
기타 매개변수
JSON_UNESCAPED_UNICODE 외에도 사용할 수 있는 상수 매개변수가 많이 있으며, 이 매개변수는 병렬로 작동할 수 있습니다. 즉, 여러 상수 매개변수가 함께 적용될 수 있습니다.
$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":"测试情况","cat":["学生 \u0026 \u0022在职\u0022"],"number":123123123,"edu":[{"name":"\u003Cb\u003E中学\u003C\/b\u003E","date":"2015-2018"},{"name":"\u003Cb\u003E大学\u003C\/b\u003E","date":"2018-2022"}]}"
이 매개변수 묶음은 실제로 & 문자, HTML 태그 등과 같은 데이터의 일부 특수 기호에 사용됩니다. 물론, 아직 완전히 표시되지 않은 일부 상수 매개변수가 있습니다. 공식 매뉴얼에서 직접 지침을 확인할 수 있습니다.
또한 json_encode()에는 반복 수준을 나타내는 세 번째 매개변수가 있습니다. 예를 들어 위에 있는 데이터는 3개 레벨의 다차원 배열이므로 정상적으로 구문 분석하려면 최소 3개를 제공해야 합니다. 다음 코드에서는 방금 1을 제공했으므로 반환된 콘텐츠는 false입니다. 즉, 인코딩이 성공할 수 없습니다. 기본적으로 이 매개변수의 값은 512입니다.
var_dump(json_encode($data, JSON_UNESCAPED_UNICODE, 1)); // bool(false)
객체 및 형식 처리
기본적으로 json_encode()는 데이터 유형에 따라 인코딩하므로 배열인 경우 인코딩된 내용은 이때 JSON의 배열 형식도 가능합니다. 배열을 객체로 인코딩하는 JSON_FORCE_OBJECT를 추가합니다.
$data = []; var_dump(json_encode($data)); // string(2) "[]" var_dump(json_encode($data, JSON_FORCE_OBJECT)); // string(2) "{}"
우리는 이전에 수학 관련 함수에 대해 이야기할 때 데이터에 NAN과 같은 데이터가 있으면 json_encode()가 이를 인코딩할 수 없다는 것을 배웠습니다. 실제로 JSON_PARTIAL_OUTPUT_ON_ERROR를 추가하여 인코딩할 수 없는 일부 값을 대체할 수 있습니다. 아래 코드에서는 이를 사용하여 NAN을 0으로 바꿀 수 있습니다.
$data = NAN; var_dump(json_encode($data)); // bool(false) var_dump(json_encode($data, JSON_PARTIAL_OUTPUT_ON_ERROR)); // 0
객체 인코딩의 속성 문제
객체의 경우 JSON 인코딩 후의 내용은 객체의 속성만 갖고 메서드는 갖지 않습니다. 결국 JSON의 가장 큰 용도는 데이터 전송이며, 방법은 데이터 전송에 실질적인 영향을 미치지 않습니다. 속성은 캡슐화에 따라 달라집니다. 공용 속성, 즉 공용 속성만 인코딩됩니다.
$data = new class { private $a = 1; protected $b = 2; public $c = 3; public function x(){ } }; var_dump(json_encode($data)); // string(7) "{"c":3}"
从这段测试代码中可以看出,protected 、 private 属性以及那个方法都不会被编码。
JSON 解码
对于 JSON 解码来说,其实更简单一些,因为 json_decode() 的常量参数没有那么多。
var_dump(json_decode($json1)); // object(stdClass)#1 (5) { // ["id"]=> // int(1) // ["name"]=> // string(12) "测试情况" // ["cat"]=> // …… // …… var_dump(json_decode($json1, true)); // array(5) { // ["id"]=> // int(1) // ["name"]=> // string(12) "测试情况" // ["cat"]=> // …… // ……
首先还是看下它的第二个参数。这个参数的作用其实从代码中就可以看出来,如果不填这个参数,也就是默认情况下它的值是 false ,那么解码出来的数据是对象格式的。而我们将这具参数设置为 true 的话,那么解码后的结果就会是数组格式的。这个也是大家非常常用的功能,就不多做解释了。
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" // }
对于这种非常长的数字格式的数据来说,如果直接 json_decode() 解码的话,它会直接转换成 科学计数法 。我们可以直接使用一个 JSON_BIGINT_AS_STRING 常量参数,将这种数据在解码的时候直接转换成字符串,其实也就是保留了数据的原始样貌。注意,这里 json_decode() 函数的参数因为有那个转换对象为数组的参数存在,所以它有四个参数,第三个参数是迭代深度,第四个就是定义这些格式化常量值的。而且它和 json_encode() 是反过来的,迭代深度参数在前,格式常量参数在后面,这里一定要注意哦!
如果数据是错误的,那么 json_decode() 会返回 NULL 。
var_dump(json_decode("", true)); // NULL var_dump(json_decode("{a:1}", true)); // NULL
错误处理
上面两段代码中我们都演示了如果编码或解码的数据有问题会出现什么情况,比如 json_encode() 会返回 false ,json_decode() 会返回 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"
没错,json_last_error() 和 json_last_error_msg() 就是返回 JSON 操作时的错误信息的。也就是说,json_encode() 和 json_decode() 在正常情况下是不会报错的,我们如果要获得错误信息,就得使用这两个函数来获取。这一点也是不少新手小同学没有注意过的地方,没错误信息,不抛出异常问题对我们的开发调试其实是非常不友好的。因为很可能找了半天都不知道问题出在哪里。
在 PHP7.3 之后,新增加了一个常量参数,可以让我们的 json_encode() 和 json_decode() 在编解码错误的时候抛出异常,这样我们就可以快速地定位问题了,现在如果大家的系统运行环境是 PHP7.3 以上的话,非常推荐使用这个常量参数让系统来抛出异常。
// 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 是对 json_encode() 和 json_decode() 都起效的。同样,只要设定了这个常量参数,我们就可以使用 try...catch 来进行捕获了。
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 序列化接口
在之前的文章中,我们学习过 使用Serializable接口来自定义PHP中类的序列化 。也就是说,通过 Serializable 接口我们可以自定义序列化的格式内容。而对于 JSON 来说,同样也提供了一个 JsonSerializable 接口来实现我自定义 JSON 编码时的对象格式内容。
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}
这是一个小的示例,只需要实现 JsonSerializable 接口中的 jsonSerialize() 方法并返回内容就可以实现这个 jsontest 对象的 JSON 编码格式的指定。这里我们只是简单地返回了数据的内容,其实和普通的 json_encode() 没什么太大的区别。下面我们通过一个复杂的例子看一下。
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 = ['学生']; } if (!$edu) { $this->edu = new stdClass; } $this->number = '学号:' . (!$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, '测试一'), JSON_UNESCAPED_UNICODE)); // string(82) "{"id":1,"name":"测试一","cat":["学生"],"number":"学号:14017495","edu":{}}" var_dump(json_encode([new Student(1, '测试一'), new Student(2, '测试二')], JSON_UNESCAPED_UNICODE)); // string(137) "[{"id":1,"name":"测试一","cat":["学生"],"number":"学号:1713936069","edu":{}},[2,"测试二",["学生"],"学号:499173036",{}]]"
在这个例子中,我们在 jsonSerialize() 做了一些操作。如果数据没有传值,比如为 null 的情况下就给一个默认值。然后在 id 为 2 的情况下返回一个普通数组。大家可以看到最后一段注释中的第二条数据的格式。
这个接口是不是很有意思,相信大家可能对上面的 json_encode() 和 json_decode() 非常熟悉了,但这个接口估计不少人真的是没接触过,是不是非常有意思。
总结
果然,什么事情都怕深挖。不学不知道,一学吓一跳,平常天天用得这么简单的 JSON 操作的相关函数其实还有很多好用的功能是我们不知道的。当然,最主要的还是看看文档,弄明白并且记住一些非常好用的常量参数,另外,抛出异常的功能也是这篇文章的重点内容,建议版本达到的朋友最好都能使用 JSON_THROW_ON_ERROR 来让错误及时抛出,及时发现哦!
测试代码:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202012/source/11.深入学习PHP中的JSON相关函数.php
参考文档:
https://www.php.net/manual/zh/book.json.php
本文转载自:https://juejin.cn/post/7001652041814638600
作者:硬核项目经理
추천 학습: "PHP 비디오 튜토리얼"
위 내용은 PHP의 JSON 관련 함수에 대해 이야기해 보겠습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

여전히 인기있는 것은 사용 편의성, 유연성 및 강력한 생태계입니다. 1) 사용 편의성과 간단한 구문은 초보자에게 첫 번째 선택입니다. 2) 웹 개발, HTTP 요청 및 데이터베이스와의 우수한 상호 작용과 밀접하게 통합되었습니다. 3) 거대한 생태계는 풍부한 도구와 라이브러리를 제공합니다. 4) 활성 커뮤니티와 오픈 소스 자연은 새로운 요구와 기술 동향에 맞게 조정됩니다.

PHP와 Python은 웹 개발, 데이터 처리 및 자동화 작업에 널리 사용되는 고급 프로그래밍 언어입니다. 1.PHP는 종종 동적 웹 사이트 및 컨텐츠 관리 시스템을 구축하는 데 사용되며 Python은 종종 웹 프레임 워크 및 데이터 과학을 구축하는 데 사용됩니다. 2.PHP는 Echo를 사용하여 콘텐츠를 출력하고 Python은 인쇄를 사용합니다. 3. 객체 지향 프로그래밍을 지원하지만 구문과 키워드는 다릅니다. 4. PHP는 약한 유형 변환을 지원하는 반면, 파이썬은 더 엄격합니다. 5. PHP 성능 최적화에는 Opcache 및 비동기 프로그래밍 사용이 포함되며 Python은 Cprofile 및 비동기 프로그래밍을 사용합니다.

PHP는 주로 절차 적 프로그래밍이지만 객체 지향 프로그래밍 (OOP)도 지원합니다. Python은 OOP, 기능 및 절차 프로그래밍을 포함한 다양한 패러다임을 지원합니다. PHP는 웹 개발에 적합하며 Python은 데이터 분석 및 기계 학습과 같은 다양한 응용 프로그램에 적합합니다.

PHP는 1994 년에 시작되었으며 Rasmuslerdorf에 의해 개발되었습니다. 원래 웹 사이트 방문자를 추적하는 데 사용되었으며 점차 서버 측 스크립팅 언어로 진화했으며 웹 개발에 널리 사용되었습니다. Python은 1980 년대 후반 Guidovan Rossum에 의해 개발되었으며 1991 년에 처음 출시되었습니다. 코드 가독성과 단순성을 강조하며 과학 컴퓨팅, 데이터 분석 및 기타 분야에 적합합니다.

PHP는 웹 개발 및 빠른 프로토 타이핑에 적합하며 Python은 데이터 과학 및 기계 학습에 적합합니다. 1.PHP는 간단한 구문과 함께 동적 웹 개발에 사용되며 빠른 개발에 적합합니다. 2. Python은 간결한 구문을 가지고 있으며 여러 분야에 적합하며 강력한 라이브러리 생태계가 있습니다.

PHP는 현대화 프로세스에서 많은 웹 사이트 및 응용 프로그램을 지원하고 프레임 워크를 통해 개발 요구에 적응하기 때문에 여전히 중요합니다. 1.PHP7은 성능을 향상시키고 새로운 기능을 소개합니다. 2. Laravel, Symfony 및 Codeigniter와 같은 현대 프레임 워크는 개발을 단순화하고 코드 품질을 향상시킵니다. 3. 성능 최적화 및 모범 사례는 응용 프로그램 효율성을 더욱 향상시킵니다.

phphassignificallyimpactedwebdevelopmentandextendsbeyondit

PHP 유형은 코드 품질과 가독성을 향상시키기위한 프롬프트입니다. 1) 스칼라 유형 팁 : PHP7.0이므로 int, float 등과 같은 기능 매개 변수에 기본 데이터 유형을 지정할 수 있습니다. 2) 반환 유형 프롬프트 : 기능 반환 값 유형의 일관성을 확인하십시오. 3) Union 유형 프롬프트 : PHP8.0이므로 기능 매개 변수 또는 반환 값에 여러 유형을 지정할 수 있습니다. 4) Nullable 유형 프롬프트 : NULL 값을 포함하고 널 값을 반환 할 수있는 기능을 포함 할 수 있습니다.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

Dreamweaver Mac版
시각적 웹 개발 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

mPDF
mPDF는 UTF-8로 인코딩된 HTML에서 PDF 파일을 생성할 수 있는 PHP 라이브러리입니다. 원저자인 Ian Back은 자신의 웹 사이트에서 "즉시" PDF 파일을 출력하고 다양한 언어를 처리하기 위해 mPDF를 작성했습니다. HTML2FPDF와 같은 원본 스크립트보다 유니코드 글꼴을 사용할 때 속도가 느리고 더 큰 파일을 생성하지만 CSS 스타일 등을 지원하고 많은 개선 사항이 있습니다. RTL(아랍어, 히브리어), CJK(중국어, 일본어, 한국어)를 포함한 거의 모든 언어를 지원합니다. 중첩된 블록 수준 요소(예: P, DIV)를 지원합니다.

안전한 시험 브라우저
안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.

Eclipse용 SAP NetWeaver 서버 어댑터
Eclipse를 SAP NetWeaver 애플리케이션 서버와 통합합니다.
