>  기사  >  백엔드 개발  >  사용자가 PHP 실행 파일을 업로드하지 못하도록 방지하는 방법(예제 포함)

사용자가 PHP 실행 파일을 업로드하지 못하도록 방지하는 방법(예제 포함)

不言
不言앞으로
2019-01-16 10:08:044001검색

이 문서의 내용은 사용자가 PHP 실행 파일을 업로드하는 것을 방지하는 방법에 대한 것입니다. 특정 참고 가치가 있으므로 도움이 될 수 있습니다.

모든 전문 PHP 개발자는 사용자가 업로드한 파일이 매우 위험하다는 것을 알고 있습니다. 백엔드 해커와 프런트엔드 해커 모두 이를 사용하여 문제를 일으킬 수 있습니다.

약 한 달 전 Reddit에서 PHP 업로드 취약점 탐지에 관한 기사를 읽고 기사를 쓰기로 결정했습니다. 사용자 darpernter가 까다로운 질문을 했습니다.

이름을 'helloworld.txt'로 바꾸더라도 공격자는 여전히 자신의 PHP 스크립트를 실행할 수 있습니까?

가장 높은 답변은 다음과 같습니다.

파일 접미사가 .txt로 변경된 경우 , 그러면 php 파일로 실행되지 않으니 안심하셔도 되지만, .php.txt 접미사를 붙여 업로드되지 않았는지 다시 한 번 확인해주세요.

죄송합니다. 위의 답변이 모두 틀린 것은 아니지만, 분명히 포괄적인 답변은 아닙니다. 놀랍게도 대부분의 답변이 매우 비슷했습니다.

이 문제를 명확하게 설명하고 싶습니다. 그래서 제가 이야기하려고 했던 내용이 좀 커져서 더 크게 만들기로 결정했습니다.

문제

사람들은 사용자에게 파일 업로드를 허용하지만, 사용자가 업로드한 파일이 서버에서 실행될까봐 걱정됩니다.

php 파일이 어떻게 실행되는지부터 살펴보세요. PHP 환경을 갖춘 서버를 가정하면 일반적으로 외부에서 PHP 파일을 실행하는 두 가지 방법이 있습니다. 하나는 http://example.com/somefile.php와 같은 URL을 사용하여 파일을 직접 요청하는 것입니다. 요즘 PHP에서 일반적으로 사용되는 두 번째 방법은 모든 요청을 index.php로 전달하고 어떻게든 이 파일에 다른 파일을 추가하는 것입니다. 따라서 PHP 파일에서 코드를 실행하는 방법에는 두 가지가 있습니다. 파일을 실행하거나 include/include_once/require/require_once 메소드를 사용하여 실행해야 하는 다른 파일을 도입하는 것입니다.

사실 세 번째 방법인 eval() 함수가 있습니다. 들어오는 문자열을 PHP 코드로 실행할 수 있습니다. 이 함수는 대부분의 CMS 시스템에서 데이터베이스에 저장된 코드를 실행하는 데 사용됩니다. eval() 함수는 매우 위험하지만, 이 함수를 사용하면 일반적으로 위험한 일을 하고 있고 다른 옵션이 없음을 확인한다는 의미입니다. 실제로 eval()에는 용도가 있으며 일부 상황에서는 매우 유용할 수 있습니다. 하지만 초보자라면 사용을 권장하지 않습니다. OWASP에서 이 기사를 참조하세요. 나는 그것에 대해 많은 것을 썼다.

그래서 파일에 있는 코드를 실행하는 방법에는 두 가지가 있습니다. 직접 실행하거나 실행 중인 파일에 도입하는 것입니다. 그렇다면 이런 일이 발생하지 않도록 하려면 어떻게 해야 할까요?

해결책?

파일에 PHP 코드가 포함되어 있는지 어떻게 알 수 있나요? 확장자 이름을 확인하세요. somefile.php처럼 .php로 끝나면 PHP 코드가 포함된 것으로 생각됩니다. .php 结尾的,像 somefile.php 我们就认为它里面有 php 代码。

如果在网站根目录下有一个 somefile.php 文件,那么在浏览器访问 http://example.com/somefile.php ,这个文件就会被执行并且输出内容到浏览器上。

但是如果我重命名这个文件会怎样?如果我把它重命名为 somefile.txt 或者是 somefile.jpg 呢?我会得到什么?我会得到它的内容。它不会被执行。它会从硬盘(或者缓存)直接被发送过来。

在这点上 reddit 社区上的答案是对的。重命名能防止一个文件被非预期的执行,那么为什么我认为这种解决方法是错的呢?

我相信你注意到我在 “解决方法” 后面加的问号。这个问号是有意义的。现在大多数网站的 URL 上几乎看不到单独的 php 文件。并且就算有,也是人为故意伪造的,因为 URL 上需要有 .php 来实现对老版本 URL 的向后兼容。

现在绝大部分 php 代码是在运行中被引入的,因为所有请求都被发送到了网站根目录的 index.php。这个文件会根据特定的规则引入其他 php 文件。这种规则可能(或者在将来会)被恶意使用。如果你应用的规则允许引入用户的文件,那么应用会容易遭到攻击,你应该立即采取措施防止用户的文件被执行。

如何防止引入用户上传的文件?

重命名文件名可以吗? --- 不,办不到!

PHP解析器不关心文件的后缀名。事实上,所有程序都不关心。双击文件,文件会被对应的程序打开。文件后缀名只是帮助操作系统识别用什么程序打开文件。只要程序有读取文件的能力,程序就可以打开任何文件。有时程序拒绝打开和操作文件。但那并不是因为后缀名,是文件内容所致。

服务器通常被设置成执行  .php  文件并将执行结果回复输出。如果你请求图片 .jpg

웹사이트의 루트 디렉터리에 somefile.php 파일이 있다면 브라우저에서 http://example.com/somefile.php에 접속하세요. 파일이 실행되고 콘텐츠가 브라우저에 출력됩니다. 🎜🎜하지만 이 파일의 이름을 바꾸면 어떻게 되나요? 이름을 somefile.txt 또는 somefile.jpg로 바꾸면 어떻게 되나요? 나는 무엇을 얻을 것인가? 내용을 가져오겠습니다. 실행되지 않습니다. 하드 디스크(또는 캐시)에서 직접 전송됩니다. 🎜🎜reddit의 답변이 바로 이 점에 있습니다. 이름을 바꾸면 파일이 예기치 않게 실행되는 것을 방지할 수 있는데, 이 솔루션이 잘못되었다고 생각하는 이유는 무엇입니까? 🎜🎜제가 "해결책" 뒤에 추가한 물음표를 보셨을 거라 생각합니다. 이 물음표는 의미가 있습니다. 요즘에는 대부분의 웹사이트 URL에서 별도의 PHP 파일을 보는 것이 거의 불가능합니다. 그리고 있다고 하더라도 이전 버전의 URL과의 호환성을 달성하려면 URL에 .php가 필요하기 때문에 의도적으로 위조된 것입니다. 🎜🎜이제 대부분의 PHP 코드는 런타임에 도입됩니다. 모든 요청이 웹사이트 루트 디렉터리의 index.php로 전송되기 때문입니다. 이 파일은 특정 규칙에 따라 다른 PHP 파일을 가져옵니다. 이러한 규칙은 악의적으로 사용될 수 있습니다. 애플리케이션의 규칙이 사용자 파일의 도입을 허용하는 경우 애플리케이션은 공격에 취약하므로 사용자 파일이 실행되지 않도록 즉시 조치를 취해야 합니다. 🎜

사용자 업로드 파일 유입을 방지하는 방법은 무엇인가요?

🎜파일 이름을 바꿔도 괜찮나요? ---  아니요, 불가능합니다! 🎜🎜PHP 파서는 파일 확장자를 신경 쓰지 않습니다. 사실 모든 프로그램은 상관하지 않습니다. 파일을 두 번 클릭하면 해당 프로그램에서 파일이 열립니다. 파일 확장자는 단순히 운영 체제가 파일을 여는 데 사용할 프로그램을 식별하는 데 도움이 됩니다. 프로그램은 파일을 읽을 수 있는 능력이 있는 한 모든 파일을 열 수 있습니다. 때때로 프로그램이 파일 열기 및 작동을 거부합니다. 하지만 이는 접미사 때문이 아니라 파일 내용 때문입니다. 🎜🎜서버는 보통 .php 파일을 실행하고 실행 결과를 다시 출력하도록 설정되어 있습니다. 이미지 .jpg를 요청하면 --- 디스크에서 변경되지 않은 상태로 반환됩니다. 서버에 jpeg 이미지를 특정 방식으로 실행하도록 요청하면 어떻게 되나요? 서버가 실행될 것인가, 실행되지 않을 것인가? 🎜

프로그램은 파일 이름에 관심이 없습니다. 파일에 이름이 있는지 또는 파일인지 여부는 중요하지 않습니다.

파일에서 PHP 코드를 실행하려면 무엇이 필요합니까?

PHP가 코드를 실행할 수 있는 상황은 최소한 두 가지가 있습니다:

  1. <?php ?> 사이의 코드 ; 코드 사이> 태그<?php  和 ?> 标记之间

  2. 代码介于 = 和 ?> 标记之间

即使文件中填充了一些奇怪的二进制数据或一些奇怪的保护名称,该标记中的代码仍然会被执行。

사용자가 PHP 실행 파일을 업로드하지 못하도록 방지하는 방법(예제 포함)

该图片没有问题

它现在很纯净。但是您可能知道 JPEG 格式允许在文件中添加一些注释。比如,拍摄照片的相机型号或坐标地址。如果我们试图在里面放一些PHP代码并尝试 include 或 require 呢?让我们来看看吧!

问题! 1

下载这个图片到你的硬盘上。或者你自己去弄一张 JPEG 图片也行。你随便用什么格式的文件都无所谓。我建议用一个 JPEG 文件来演示,主要是因为它是一张图片且易于在其中进行文本编辑。我用的是一个 Windows的笔记本,目前我手头上没有 Apple 或 Linux(或其他UNIX系的系统)的笔记本。所以一会我会发一个这个 OS 下的屏幕快照。但是我确信你肯定也能做这个事。

用以下这段 PHP 代码建个文件:

<h1>Problem?</h1>
<img  alt="사용자가 PHP 실행 파일을 업로드하지 못하도록 방지하는 방법(예제 포함)" >
<?php include "./troll-face.jpg";
  1. 保存一个图片命名为troll-face.jpg

  2. 把图片和 php 脚本文件都放在同一个文件夹下

  3. 打开浏览器请求这个 php 文件

如果你把你的 php 文件命名为 index.php,然后把它放在文件根目录或者放在你网站目录下的任何一个文件目录中。

如果你准确完成了上述步骤,你就可以看到这个画面:

사용자가 PHP 실행 파일을 업로드하지 못하도록 방지하는 방법(예제 포함)

到此这都没毛病。没 PHP 代码展示,也没有 PHP 代码被执行。

现在,我们来添加一个问题:

  1. 打开文件属性对话框或运行一些允许编辑 EXIF 信息的应用程序

  2. 切换到 Details 选项卡或以其他方式编辑该信息

  3. 向下滚动到 camera 参数

  4. 将下面代码复制到 “camera maker” 字段后面:

<?php  echo "<h2>Yep, a problem!"; phpinfo(); ?>

사용자가 PHP 실행 파일을 업로드하지 못하도록 방지하는 방법(예제 포함)

刷新页面!

사용자가 PHP 실행 파일을 업로드하지 못하도록 방지하는 방법(예제 포함)

很明显出现了一点问题!

您在页面上看到了该图片。相同的图片还存在页面的 PHP 代码中。图片的代码也被执行了。

我们该怎么做?!!1

长话短说: 如果我们不在程序种引入这些不安全的文件,文件中的脚本就不会执行。

仔细看下面的例子。

最终答案?

如果有人在某处看到我错了 - 请纠正我,这是一个严重的问题。

PHP是一种脚本语言。您总是需要引用一些动态组合路径的文件。因此,为了保护服务器,您必须检查路径并防止混淆您的站点文件和用户上传或创建的文件。如果用户的文件与应用程序文件分开,则可以在使用上传或创建文件之前检查文件的路径。如果它位于您的应用程序脚本允许的文件夹中 - 那么它可以使用 include_once 或 require 或 require_once 引入这个文件。如果不是--那么就不引入它。

如何进行检查?这很简单。你只需要将 $folder (文件)路径与一个允许程序引入文件 ( $file ) 的路径文件夹进行比较。

// 不好的例子,不要用!
if (substr($file, 0, strlen($folder)) === $folder) {
  include $file;
}

如果  $folder 的存放路径是 /path/to/folder  而且  $file  的存放路径是  /path/to/folder/and/file

🎜=?> 태그 사이의 코드🎜🎜 짝수 파일이 이상한 바이너리 데이터나 이상한 보호된 이름으로 채워져 있으면 해당 태그의 코드는 계속 실행됩니다. 🎜🎜사용자가 PHP 실행 파일을 업로드하지 못하도록 방지하는 방법(예제 포함)🎜🎜이미지에는 이상이 없습니다🎜🎜지금은 순수합니다. 그러나 JPEG 형식을 사용하면 파일에 일부 주석을 추가할 수 있다는 사실을 알고 계실 것입니다. 예를 들어 사진을 찍은 카메라 모델이나 좌표 주소입니다. 거기에 PHP 코드를 삽입하고 를 포함하거나 요구하려고 하면 어떻게 될까요? 살펴보자! 🎜🎜질문! 1🎜🎜이 이미지를 하드 드라이브에 다운로드하세요. 아니면 JPEG 이미지를 직접 얻을 수도 있습니다. 어떤 파일 형식을 사용하는지는 중요하지 않습니다. 프리젠테이션에는 JPEG 파일을 사용하는 것이 좋습니다. 주로 이미지이고 텍스트 편집이 쉽기 때문입니다. 저는 Windows 노트북을 사용하고 있는데 현재 Apple이나 Linux(또는 기타 UNIX 기반 시스템) 노트북이 없습니다. 그래서 잠시 후에 이 OS의 스크린샷을 게시하겠습니다. 하지만 나는 당신도 이것을 할 수 있다고 확신합니다. 🎜🎜다음 PHP 코드를 사용하여 파일을 만듭니다. 🎜
/path/to/folder/../../../../../../../another/path/from/root/
🎜🎜🎜이미지 이름을 troll-face.jpg🎜🎜🎜저장합니다. 이미지와 PHP 스크립트 파일을 같은 곳에 넣습니다. 폴더🎜🎜🎜브라우저를 열어 이 PHP 파일을 요청하세요🎜🎜PHP 파일 이름을 index.php로 지정하고 파일 루트에 넣으세요. 디렉토리 또는 웹사이트 디렉토리 아래의 파일 디렉토리. 🎜🎜위 단계를 정확하게 완료하시면 다음 화면을 보실 수 있습니다: 🎜🎜사용자가 PHP 실행 파일을 업로드하지 못하도록 방지하는 방법(예제 포함)🎜🎜지금까지는 문제가 없습니다. PHP 코드가 표시되지 않으며 PHP 코드가 실행되지 않습니다. 🎜🎜이제 질문을 추가해 보겠습니다. 🎜🎜🎜🎜파일 속성 대화 상자를 열거나 EXIF ​​​​정보 편집을 허용하는 일부 애플리케이션을 실행🎜🎜🎜세부 정보 탭으로 전환하거나 정보를 편집하세요🎜🎜🎜카메라 매개변수까지 아래로 스크롤🎜🎜🎜"카메라 메이커" 필드 뒤에 다음 코드를 복사하세요: 🎜
include $folder . "/" . $_GET['some']; // or $_POST, or whatever
🎜🎜🎜페이지를 새로고침하세요! 🎜🎜사용자가 PHP 실행 파일을 업로드하지 못하도록 방지하는 방법(예제 포함)🎜🎜분명히 뭔가 잘못됐네요! 🎜🎜페이지에 이미지가 있습니다. 페이지의 PHP 코드에도 동일한 이미지가 존재합니다. 이미지에 대한 코드도 실행됩니다. 🎜🎜어떻게 해야 할까요?!! 1🎜🎜짧게 말하면: 이러한 안전하지 않은 파일을 프로그램에 포함하지 않으면 파일의 스크립트가 실행되지 않습니다. 🎜🎜아래 예를 주의 깊게 살펴보세요. 🎜🎜최종 답변은? 🎜🎜어디서 내가 틀렸다는 것을 본 사람이 있다면 바로잡아주세요. 심각한 문제입니다. 🎜🎜PHP는 스크립팅 언어입니다. 경로를 동적으로 결합하는 일부 파일을 항상 참조해야 합니다. 따라서 서버를 보호하려면 경로를 확인하고 사이트 파일과 사용자가 업로드하거나 생성한 파일 간의 혼동을 방지해야 합니다. 사용자 파일이 애플리케이션 파일과 별도인 경우 업로드 또는 생성을 사용하기 전에 파일 경로를 확인할 수 있습니다. 응용 프로그램 스크립트가 허용하는 폴더에 있는 경우 include_once나 require 또는 require_once를 사용하여 이 파일을 포함할 수 있습니다. 그렇지 않다면 소개하지 마세요. 🎜🎜확인하는 방법은 무엇인가요? 매우 간단합니다. $folder (파일) 경로를 프로그램이 파일( $file )을 가져올 수 있는 경로 폴더와 비교하면 됩니다. 🎜
move_uploaded_file($filename, $folder . '/' . $filename);
🎜$folder의 저장 경로가 /path/to/folder이고 $file의 저장 경로가 /인 경우 path/ to/folder/and/file, 그런 다음 코드에서 substr() 함수를 사용하여 해당 경로를 판단을 위해 음수 문자열로 바꿉니다. 파일이 다른 폴더에 있는 경우---이 문자열은 그렇지 않습니다. 동일한. 그 반대가 사실입니다. 🎜

上面的代码有两个重要的问题。如果 file 路径是  /path/to/folderABC/and/file,很明显,该文件也不在允许引入的文件夹中。通过向两个路径添加斜杠可以防止这种情况。我们在这里向文件路径添加斜杠并不重要,因为我们只需要比较两个字符串。

举个例子: 如果 folder 路径是  /path/to/folder  并且 file 路径是 /path/to/folder/and/file ,那么从 file 提取和 folder 具有相同数量的字符,那么 $ folder 将是 /path/to/folder

再比如 folder 路径是 /path/to/folder 并且 file 路径是 /path/to/folderABC/and/file, 那么从 file 中提取 folder 具有相同数量的字符,和 $folder一样,并且将再次成为/path/to/folder,这种都是错误的,这不是我们期望的结果。

因此,在 /path/to/folder/ 添加斜杠后,与 /path/to/folder/and/file 的提取部分 /path/to/folder/ 相同就是安全的。

如果将 /path/to/folder//path/to/folderABC/and/file 的提取部分 / path/to/folderA ,很明显二个字符串不一样。

这就是我们期望得到的。但还有另一个问题。这并不明显。我敢肯定,如果我问你,你看到这里有一个灾难性的漏洞 - 你不会猜到它在哪里。你也许已经在经验中使用过这个东西,甚至可能就在今天。现在,您将看到漏洞是如何隐晦和显而易见。往下看。

/../

假想一个很常见的场景。

有这么一个网站。用户可以上传文件到该站点。所有的文件都位于一个特定的目录下。有一个包含用户文件的脚本。脚本自上而下进行查找是否包含用户的输入(直接或间接)路径---那这个脚本可以通过如下方式进行路径伪造:

/path/to/folder/../../../../../../../another/path/from/root/

举例。用户发起请求,你的脚本中包含了一个基于类似如下用户输入路径的文件:

include $folder . "/" . $_GET['some']; // or $_POST, or whatever

你麻烦大了。有天用户发送一个 ../../../../../../etc/.passwd 这种或其他请求,你就哭吧。

再不然。假如有人让你的脚本加载一个他想要的文件,你就废了。它不一定就只是出现在用户文件中。它可能是你的CMS或你自己文件的一些插件(别相信任何人),甚至是应用程序逻辑中的错误等。

或者

用户可能会上传一个名为 file.php 的文件,你会把它和其他的用户文件一样放在一个特定的文件夹里面:

move_uploaded_file($filename, $folder . '/' . $filename);

用户的文件就存放在那里,你必须常常检查从来没有包含该文件夹中的文件,目前来看,所有的东西都挺正常的。通常,用户发给你的文件不会包含斜杠或者其他特殊字符,因为这是被系统文件系统禁止的。之所以这样,是因为通常情况下浏览器发给你的文件是在真实文件系统中创建的,同时它的名字是一些真实存在的文件的名字。

但是 http 请求允许用户发送任何字符。所以如果某人伪造请求创建名为 ../../../../../../var/www/yoursite.com/index.php 的文件---这行代码会覆盖你的 index.php 文件,如果 index.php 处于在上述路径的话。

所有的初学者都希望通过过滤 「..」或者斜杠来解决这个问题,但是这种做法是错误的,由于你在安全方面还缺乏经验。同时你必须(是的,必须)明白一个简单的事情:你永远无法在安全和密码学方面的获得足够的知识。这句话的意思是,如果你懂得了「两个点和斜杠」的漏洞,但这不代表你知道所有其他的缺陷、攻击和其他特殊字符,你也不知道在文件写入文件系统或数据库时可能发生的代码转换。

解决方案和答案

为了解决这个问题,PHP中内置了一些特殊函数方法,只是为了在这种情况下使用。

basename()

第一个解决方案 --- basename() 它从路径结束时提取路径的一部分,直到它遇到第一个斜杠,但忽略字符串末尾的斜杠,参见示例。无论如何,你会收到一个安全的文件名。如果你觉得安全 - 那么是的这很安全。如果它被不法上传利用 - 你可以使用它来校验文件名是否安全。

realpath()

另一个解决方案 --- realpath()它将上传文件路径转换规范化的绝对路径名,从根开始,并且根本不包含任何不安全因素。它甚至会将符号链接转换为此符号链接指向的路径。

因此,您可以使用这两个函数来检查上传文件的路径。要检查这个文件路径到底是否真正属于此文件夹路径。

我的代码

我编写了一个函数来提供如上的检查。我并不是专家,所以风险请自行承担。代码如下。

<?php /**
 * Example for the article at medium.com
 * Created by Igor Data.
 * User: igordata
 * Date: 2017-01-23
 * @link https://medium.com/@igordata/php-running-jpg-as-php-or-how-to-prevent-execution-of-user-uploaded-files-6ff021897389 Read the article
 */
/**
 * 检查某个路径是否在指定文件夹内。若为真,返回此路径,否则返回 false。
 * @param String $path 被检查的路径
 * @param String $folder 文件夹的路径,$path 必须在此文件夹内
 * @return bool|string 失败返回 false,成功返回 $path
 *
 */
function checkPathIsInFolder($path, $folder) {
    if ($path === &#39;&#39; OR $path === null OR $path === false OR $folder === &#39;&#39; OR $folder === null OR $folder === false) {
      /* 不能使用 empty() 因为有可能像 "0" 这样的字符串也是有效的路径 */
        return false;
    }
    $folderRealpath = realpath($folder);
    $pathRealpath = realpath($path);
    if ($pathRealpath === false OR $folderRealpath === false) {
        // Some of paths is empty
        return false;
    }
    $folderRealpath = rtrim($folderRealpath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
    $pathRealpath = rtrim($pathRealpath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
    if (strlen($pathRealpath) < strlen($folderRealpath)) {
        // 文件路径比文件夹路径短,那么这个文件不可能在此文件夹内。
        return false;
    }
    if (substr($pathRealpath, 0, strlen($folderRealpath)) !== $folderRealpath) {
        // 文件夹的路径不等于它必须位于的文件夹的路径。
        return false;
    }
    // OK
    return $path;
}

结语。

  • 必须过滤用户输入,文件名也属于用户输入,所以一定要检查文件名。记得使用 basename() 。

  • 必须检查你想存放用户文件的路径,永远不要将这个路径和应用目录混合在一起。文件路径必须由某个文件夹的字符串路径,以及 basename($filename) 组成。文件被写入之前,一定要检查最终组成的文件路径。

  • 在你引用某个文件前,必须检查路径,并且是严格检查。

  • 记得使用一些特殊的函数,因为你可能并不了解某些弱点或漏洞。

  • 并且,很明显,这与文件后缀或 mime-type 无关。JPEG 允许字符串存在于文件内,所以一张合法的 JPEG 图片能够同时包含合法的 PHP 脚本。

不要信任用户。不要信任浏览器。构建似乎所有人都在提交病毒的后端。

当然,也不必害怕,这其实比看起来的简单。只要记住 “不要信任用户”  以及 “有功能解决此问题” 便可。

위 내용은 사용자가 PHP 실행 파일을 업로드하지 못하도록 방지하는 방법(예제 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제