> 백엔드 개발 > PHP 튜토리얼 > PHP의 자동 로딩 기능에 대한 자세한 설명

PHP의 자동 로딩 기능에 대한 자세한 설명

零到壹度
풀어 주다: 2023-03-22 11:46:01
원래의
1662명이 탐색했습니다.

이 글은 PHP의 자동 로딩 기능을 요약한 글로, PHP의 자동 로딩 기능, PHP의 네임스페이스, PHP의 PSR0 및 PSR4 표준 등을 다루고 있습니다.

1. PHP 자동 로딩 기능

PHP 자동 로딩 기능의 유래

PHP 개발 과정에서, 외부에서 클래스를 도입하고 싶다면 보통 include 및 require 메소드를 사용하여 이 클래스를 정의하는 파일을 포함하십시오. 소규모로 개발한다면 큰 문제는 없습니다. 그러나 대규모 개발 프로젝트에서 이 방법을 사용하면 몇 가지 숨겨진 문제가 발생합니다. PHP 파일이 다른 많은 클래스를 사용해야 하는 경우 많은 require/include 문이 필요하므로 불필요한 클래스 파일이 누락되거나 포함될 수 있습니다. . 많은 수의 파일에 다른 클래스를 사용해야 하는 경우 각 파일에 올바른 클래스 파일이 포함되어 있는지 확인하는 것은 악몽이 되며 require_once 비용이 많이 듭니다.

PHP5는 클래스의 자동 로딩(autoload) 메커니즘으로 이 문제에 대한 해결책을 제공합니다. 자동 로드 메커니즘을 사용하면 처음부터 모든 클래스 파일을 포함하는 대신 PHP 프로그램이 클래스를 사용할 때만 클래스 파일을 자동으로 포함할 수 있습니다. 이 메커니즘을 지연 로딩이라고도 합니다.

요약하자면 자동 로딩 기능은 다음과 같은 장점을 제공합니다:

  1. 클래스를 사용하기 전에 include나 require를 할 필요가 없습니다

  2. require/include 파일은 다음과 같은 경우에만 구현됩니다. 클래스를 사용하면 중복 파일이 필요/포함되지 않습니다.

  3. 가져온 클래스의 실제 디스크 주소를 고려할 필요가 없으므로 논리 파일과 물리 파일이 분리됩니다.


자동 로딩 기능에 대해 더 자세히 알고 싶다면 다음 정보를 확인하세요:
PHP의 클래스 자동 로딩 메커니즘
PHP의 자동 로딩 메커니즘 구현 분석

PHP 자동 로딩 기능 __autoload()

보통 PHP5가 클래스를 사용할 때 클래스가 로드되지 않은 것을 발견하면 자동으로 _autoload() 함수를 실행합니다. 프로그램 예, 이 함수에서는 사용해야 하는 클래스를 로드할 수 있습니다. 다음은 간단한 예입니다.

<span style="font-size: 16px;">function __autoload($classname) {  <br>  require_once ($classname . "class.php"); <br>}<br></span>
로그인 후 복사

간단한 예에서는 ".class.php" 확장자를 사용하여 클래스 이름을 직접 추가하여 클래스 파일 이름을 구성한 다음 require_once를 사용하여 로드합니다. 이 예에서 자동 로드는 최소한 세 가지 작업을 수행해야 함을 알 수 있습니다.

  1. 클래스 이름을 기반으로 클래스 파일 이름 결정

  2. 클래스 파일이 있는 디스크 경로 결정 위치(가장 간단한 예에서는 클래스가 클래스를 호출하는 PHP 프로그램 파일과 동일한 폴더에 있음)

  3. 클래스를 디스크 파일에서 시스템으로 로드합니다.


세 번째 단계는 가장 간단합니다. include/require를 사용하면 됩니다. 첫 번째와 두 번째 단계의 기능을 구현하려면 개발 중에 클래스 이름과 디스크 파일 간의 매핑 방법을 합의해야 합니다. 이 방법을 통해서만 클래스 이름을 기반으로 해당 디스크 파일을 찾을 수 있습니다.

포함할 클래스 파일 수가 많은 경우 해당 규칙만 결정한 다음 __autoload() 함수에서 클래스 이름을 실제 디스크 파일과 일치시켜 지연 로딩 효과를 얻으면 됩니다. . 여기서도 _autoload() 함수 구현에서 가장 중요한 것은 클래스 이름과 실제 디스크 파일 간의 매핑 규칙 구현이라는 것을 알 수 있습니다.

__autoload() 함수 관련 문제

시스템 구현 시 다른 많은 클래스 라이브러리를 사용해야 하는 경우 이러한 클래스 라이브러리는 다른 개발자가 작성했을 수 있으며 해당 클래스 이름이 실제 클래스와 다를 수 있습니다. 디스크 파일의 매핑 규칙이 다릅니다. 이때, 클래스 라이브러리 파일의 자동 로딩을 구현하려면 __autoload() 함수에서 모든 매핑 규칙을 구현해야 합니다. 이 경우 autoload() 함수는 구현하기가 매우 복잡하거나 불가능할 수도 있습니다. 결국, autoload() 함수는 매우 비대해 질 수 있으며, 구현 가능하더라도 향후 유지 관리 및 시스템 효율성에 큰 부정적인 영향을 미칠 것입니다.

그래서 문제는 어디에 있나요? 문제는 _autoload()가 한 번만 정의할 수 있는 전역 함수이고 유연성이 부족하다는 점입니다. 따라서 클래스 이름과 파일 이름에 해당하는 모든 논리적 규칙을 하나의 함수로 구현해야 하므로 이 함수가 비대해집니다. 그렇다면 이 문제를 해결하는 방법은 무엇입니까? 대답은 _autoload 호출 스택을 사용하고, 서로 다른 _autoload 함수에 서로 다른 매핑 관계를 작성한 다음 이를 균일하게 등록하고 관리하는 것입니다. 이것이 PHP5에 도입된 SPL Autoload입니다.

SPL Autoload

SPL은 Standard PHP Library의 약어입니다. 이는 PHP5에 도입된 확장 라이브러리입니다. 주요 기능에는 자동 로드 메커니즘과 다양한 Iterator 인터페이스 또는 클래스의 구현이 포함됩니다. SPL 자동 로드에는 몇 가지 특정 기능이 있습니다.

  1. spl_autoload_register: __autoload() 함수 등록

  2. spl_autoload_unregister: 등록된 함수 등록 취소

  3. s autoload_functions: 등록된 모든 함수를 반환합니다

  4. spl_autoload_call: 등록된 모든 함수를 사용하여 클래스 로드

  5. spl_autoload: __autoload()의 기본 구현

  6. spl_autoload_extions: spl_autoload 함수에서 사용하는 기본 파일 확장자를 등록하고 반환합니다.


이러한 함수의 자세한 사용법은 php

spl_autoload에 대한 자세한 설명에서 찾을 수 있습니다. 간단히 말해서, spl_autoload는 SPL 자체 정의된 __autoload() 함수입니다. 등록된 디렉터리(set_include_path 설정) $classname과 동일한 이름을 가진 .php/.inc 파일을 찾습니다. 물론 확장명(spl_autoload_exionsions)을 등록하여 특정 유형의 파일을 지정할 수도 있습니다.

그리고 spl_autoload_register()는 위에서 언급한 자동 로드 호출 스택입니다. PHP가 클래스 이름을 찾을 수 없으면 PHP는 이 스택을 호출하고 사용자 정의 _autoload를 호출합니다. () 기능을 하나씩 실행하여 자동 로딩 기능을 실현합니다. 이 함수에 매개변수를 입력하지 않으면 spl_autoload() 함수가 등록됩니다.

좋아요, 이것은 PHP 자동 로딩의 최하위 레이어입니다. 등록 메커니즘은 이미 매우 유연하지만 무엇이 빠졌나요? 위에서 말했듯이 자동 로딩의 핵심은 클래스 이름과 파일의 매핑입니다. 프레임워크마다 이 매핑 관계에 대한 방법이 다릅니다. 매우 유연하지만 너무 유연하면 PHP에는 특별한 문제가 있습니다. 이 매핑 관계에 대한 사양은 표준에서 PSR PSR0 및 PSR4입니다.

그러나 PSR0과 PSR4에 대해 이야기하기 전에 PHP의 네임스페이스 문제도 이해해야 합니다. 왜냐하면 이 두 표준은 실제로 클래스 이름과 디렉터리 파일의 매핑이 아니라 네임스페이스와 파일의 매핑을 목표로 하기 때문입니다. 왜 이런 일이 발생합니까? 제가 이해하는 표준 객체지향 PHP 아이디어에서는 네임스페이스가 어느 정도 클래스 이름의 별칭인데 네임스페이스를 도입해야 하는 이유와 네임스페이스의 장점은 무엇인가요?

2. 네임스페이스


네임스페이스를 이해하려면 먼저 공식 문서에서 네임스페이스 소개를 살펴보세요.

네임스페이스란 무엇인가요? 광범위하게 말하면 네임스페이스는 사물을 캡슐화하는 방법입니다. 이 추상적인 개념은 여러 곳에서 찾아볼 수 있습니다. 예를 들어 디렉터리는 운영 체제에서 관련 파일을 그룹화하는 데 사용되며 디렉터리에 있는 파일의 네임스페이스 역할을 합니다. 예를 들어, foo.txt 파일은 /home/greg 및 /home/other 디렉토리에 동시에 존재할 수 있지만 두 개의 foo.txt 파일이 동일한 디렉토리에 존재할 수는 없습니다. 또한 /home/greg 디렉토리 외부에서 foo.txt 파일에 액세스할 때 /home/greg/foo.txt를 가져오려면 파일 이름 앞에 디렉토리 이름과 디렉토리 구분 기호를 넣어야 합니다. 이 원칙을 프로그래밍 분야에 적용한 것이 네임스페이스의 개념입니다.
PHP에서 네임스페이스는 클래스 라이브러리나 애플리케이션을 작성할 때 클래스나 함수와 같은 재사용 가능한 코드를 만들 때 발생하는 두 가지 유형의 문제를 해결하는 데 사용됩니다.
1 사용자가 작성한 코드와 PHP 내부 클래스/함수/상수 또는 세 번째 코드 간의 이름 충돌 파티 클래스/함수/상수
2 소스 코드의 가독성을 높이기 위해 매우 긴 식별자 이름(일반적으로 첫 번째 유형의 문제를 완화하기 위해 정의됨)에 대해 (또는 짧은) 이름을 만듭니다.
PHP 네임스페이스는 관련 클래스, 함수 및 상수를 그룹화하는 방법을 제공합니다.

  
간단히 말하면, PHP는 프로그램에서 동일한 이름을 가진 두 개의 클래스, 함수 또는 변수 이름을 허용하지 않습니다. 그래서 일부 사람들은 동일한 이름을 가지지 않아도 괜찮지 않습니까? 실제로 많은 대규모 프로그램은 많은 타사 라이브러리에 의존하고 있으며 이는 공식 웹사이트에서 발생하는 첫 번째 문제입니다. 그렇다면 이 문제를 해결하는 방법은 무엇입니까? 네임스페이스가 없을 때 가난한 프로그래머는 클래스 이름 a_b_c_d_e_f만 지정할 수 있습니다. 여기서 a/b/c/d/e/f는 일반적으로 고유한 특정 의미를 가지므로 일반적으로 충돌이 없지만 이 긴 클래스 이름은 쓰기가 피곤하고 읽기가 더 불편합니다. 따라서 PHP5에서는 클래스 이름이 클래스 이름이고, 네임스페이스가 네임스페이스가 되어 프로그램을 작성/읽을 때 머신이 네임스페이스를 보게 되어 문제가 해결됩니다.

또한 네임스페이스는 관련 클래스, 함수 및 상수를 그룹화하는 방법을 제공합니다. 이는 객체지향 언어 네임스페이스를 잘 활용하는 방법이기도 합니다. 특정 목적에 필요한 클래스, 변수, 함수를 네임스페이스에 기록하고 캡슐화합니다.

클래스 이름 문제가 해결되었으며 마침내 PSR 표준으로 돌아갈 수 있습니다. 그러면 PSR0과 PSR4는 파일과 네임스페이스 간의 매핑 관계를 어떻게 표준화합니까? 대답은 네임스페이스 이름 지정(글쎄 좀 혼란스럽습니다), 클래스 파일 디렉터리 위치 및 둘 사이의 매핑 관계에 대한 제한 사항입니다. 더 자세한 설명은 최신 PHP 새로운 기능 시리즈(1) - 네임스페이스

3. PSR 표준

에서 확인할 수 있습니다.

PSR0과 PSR4에 대해 이야기하기 전에 PSR 표준을 소개하겠습니다. PSR 표준의 창시자이자 표준화자는 PHP-FIG이며 웹사이트는 www.php-fig.org입니다. PSR 사양을 발명하고 만든 것이 바로 이 컨소시엄이었습니다. Fig는 Framework Interoperability Group의 약어로 2009년에 여러 오픈 소스 프레임워크 개발자에 의해 설립되었으며, 이후 많은 회원이 선정되었습니다. 비록 "공식적인" 조직은 아니지만 커뮤니티의 큰 부분을 차지하기도 합니다. . 조직의 목적은 각 회사의 개발 스타일이 프로그램 디자이너의 발전을 방해하는 문제를 피하기 위해 가장 낮은 수준의 제한으로 각 프로젝트의 코딩 표준을 통일하는 것입니다. 그래서 모두가 표준 권장 사항을 제안하는 PSR을 발명하고 요약했습니다. (표준 권고안 제안) 표준 제안의 약어).

구체적이고 자세한 사양을 볼 수 있습니다.
PSR 사양의 PHP

PSR0 표준

PRS-0 사양은 주로 일부 자동 로딩 표준을 공식화하기 위해 발행한 최초의 사양 세트입니다( 자동 로딩 표준) PSR-0 필수 요구 사항:

1. 정규화된 네임스페이스 및 클래스는 "< Vendor Name>(< Namespace>)*< Class Name> ”
2. 각 네임스페이스에는 최상위 네임스페이스("공급업체 이름" 공급자 이름)가 있어야 합니다
3. 각 네임스페이스에는 여러 개의 하위 네임스페이스가 있을 수 있습니다
4. 파일 시스템에서 로드할 때 각 네임스페이스의 구분 기호(/)를 다음으로 변환해야 합니다. DIRECTORY_SEPARATOR(운영 체제 경로 구분 기호)
5. 클래스 이름에서 각 밑줄(_) 기호는 DIRECTORY_SEPARATOR(운영 체제 경로 구분 기호)로 변환되어야 합니다. 네임스페이스 내에서 underscore_ 기호는 (특별한) 의미가 없습니다.
6. 파일 시스템에서 로드할 때 정규화된 네임스페이스와 클래스는 .php로 끝나야 합니다.
7. Verdor 이름, 네임스페이스 및 클래스 이름은 대문자와 소문자로 구성될 수 있습니다(대소문자 구분)

  
구체적인 규칙은 다소 혼란스러울 수 있으므로 처음부터 시작하겠습니다.

먼저 PSR0 표준의 일반적인 내용을 살펴보겠습니다. 1, 2, 3, 7조는 네임스페이스의 이름을 제한하고, 4조와 5조는 네임스페이스와 파일 디렉터리 간의 매핑 관계를 6개로 제한합니다. 파일 확장자입니다.

앞서 말했듯이 PSR 표준은 네임스페이스와 그것이 위치한 파일 디렉터리 간의 매핑 관계를 어떻게 표준화합니까? 이는 네임스페이스의 이름, 파일 디렉터리의 위치 및 둘 사이의 매핑 관계를 제한함으로써 가능합니다.

그럼 파일이 있는 디렉터리의 위치 제한은 어디에 있는지 물어봐야 할 수도 있습니다. 실제로 대답은 다음과 같습니다.
  

제한된 네임스페이스 이름 + 제한된 네임스페이스 이름 및 파일 디렉터리 매핑 = 제한된 파일 디렉터리

  자, 먼저 생각해 보겠습니다. 특정 프로그램에 대해 PSR0 표준을 지원하려면 어떤 조정이 필요한가요? ?

  1. 먼저 프로그램은 PSR0 표준 4조와 5조를 준수하는 매핑 함수를 정의한 다음 이 함수를 spl_register()에 등록해야 합니다.

  2. 두 번째로 새 네임스페이스를 정의합니다. , 네임스페이스 이름 및 파일의 디렉터리 위치는 조항 1, 2, 3, 7을 준수해야 합니다.

일반적으로 코드 유지 관리의 편의를 위해 파일당 하나의 네임스페이스만 정의합니다.

자, PSR0 표준을 준수하는 네임스페이스 이름을 얻었습니다. PSR0 표준을 준수하는 매핑 관계를 통해 파일을 올바르게 저장하면 PSR0 표준을 준수하는 파일 디렉터리 주소를 얻을 수 있습니다. PSR0 표준에서는 파일을 성공적으로 요구할 수 있고 이 네임스페이스를 사용할 수 있습니다. 놀랍지 않나요?

다음으로 PSR0 표준이 무엇을 명시하고 있는지 자세히 살펴보겠습니다.

위의 PSR0 표준에 대해 이야기하기 위해 laravel에 있는 타사 라이브러리 Symfony의 /Symfony/Core/Request 네임스페이스 중 하나를 예로 들어 보겠습니다.

  1. 정규화된 네임스페이스 및 클래스는 다음 구조를 준수해야 합니다. "< 공급업체 이름>(< 네임스페이스>)*< 클래스 이름>"

위에 표시됨 /Symfony 는 타사 라이브러리의 이름인 공급업체 이름이고, /Core는 일반적으로 네임스페이스의 일부 속성 정보인 네임스페이스 이름입니다(예: 요청은 Symfony의 핵심 기능입니다). 우리 네임스페이스의 이름은 표준 사양은 사람들이 네임스페이스의 소스와 기능을 매우 명확하게 볼 수 있도록 하는 것이며 이는 코드 유지 관리에 도움이 됩니다.

2. 각 네임스페이스에는 최상위 네임스페이스("공급업체 이름" 공급자 이름)가 있어야 합니다

즉, 각 네임스페이스에는 /Symfony와 유사한 최상위 네임스페이스가 있어야 합니다. 왜 그런 규칙이 있는 걸까요? PSR0 표준은 최상위 네임스페이스 이후의 매핑 관계, 즉 /Symfony가 연결되어야 하는 /Symfony/Core/Request 부분만 사용자 또는 프레임워크 자체에서 정의하기 때문입니다. 소위 최상위 네임스페이스는 사용자 정의된 매핑 관계가 있는 네임스페이스이며 일반적으로 공급자 이름(타사 라이브러리의 이름)입니다. 즉, 최상위 네임스페이스가 자동 로딩의 기반이 됩니다. 기준은 왜 이렇게 정해져 있는 걸까요? 이유는 매우 간단합니다. /Symfony/Core/Transport/Request 네임스페이스가 있고 다른 네임스페이스는 /Symfony/Core/Transport/Request1이고, 최상위 네임스페이스가 없으면 두 개의 경로를 작성해야 합니다. 네임스페이스에 해당하여 Request2, Request3이 있으면 어떻게 될까요? 최상위 네임스페이스 /Symfony를 사용하면 이에 해당하는 디렉터리만 필요하고 나머지는 PSR 표준을 사용하여 구문 분석할 수 있습니다.

3. 각 네임스페이스는 여러 개의 하위 네임스페이스를 가질 수 있습니다

요청은 /Symfony/Core/Request로 정의하거나 /Symfony/Core/Transport로 정의할 수 있습니다. /Request, / Core 네임스페이스 아래에는 여러 개의 하위 네임스페이스가 있을 수 있습니다. 여기에 넣을 네임스페이스 레이어 수를 정의할 수 있습니다.

  

4. 파일 시스템에서 로드할 때 각 네임스페이스의 구분 기호(/)가 DIRECTORY_SEPARATOR(운영 체제 경로 구분 기호)

이제 마침내 매핑 표준화에 이르렀습니다. 네임스페이스의 / 기호를 경로 구분 기호로 변환해야 합니다. 이는 /Symfony/Core/Request 네임스페이스를 SymfonyCoreRequest와 같은 디렉터리 구조로 변환해야 함을 의미합니다.

5. 클래스 이름에서 각 밑줄 _ 기호는 DIRECTORYSEPARATOR(운영 체제 경로 구분 기호)로 변환되어야 합니다. 네임스페이스에서 밑줄 기호는 (특별한) 의미가 없습니다.

이 문장의 의미는 네임스페이스가 /Symfony/Core/Request_a라면 이를 SymfonyCoreRequesta와 같은 디렉터리에 매핑해야 한다는 것입니다. 왜 그런 조항이 있는 걸까요? 이는 PHP5 이전에는 네임스페이스가 없었고 프로그래머는 Symfony_Core_Request_a로만 이름을 지정할 수 있었기 때문입니다. PSR0의 이 조항은 이러한 상황과 호환됩니다.
나머지 두 가지는 매우 간단하므로 자세히 설명하지 않겠습니다.

이러한 네임스페이스 명명 규칙과 매핑 표준을 통해 네임스페이스가 위치한 파일을 어디에 넣어야 할지 추론할 수 있습니다. Symfony/Core/Request를 예로 들면 해당 디렉터리는 /path/to/project/vendor/Symfony/Core/Request.php입니다. 여기서 /path/to/project는 디스크에 있는 프로젝트의 위치이고 /path입니다. /to /project/vendor는 프로젝트에서 사용하는 모든 타사 라이브러리가 있는 디렉터리입니다. /path/to/project/vendor/Symfony는 최상위 네임스페이스/Symfony에 해당하는 디렉터리입니다. 아래 파일 디렉터리는 PSR0 표준에 따라 설정됩니다.

/Symfony/Core/Request => /Symfony/Core/Request.php

모든 것이 완벽하죠? 아니요, 여전히 몇 가지 결함이 있습니다.

  1. 네임스페이스 없이도 여전히 호환 가능해야 합니까?

  2. PSR0 표준에 따르면 네임스페이스 /A/B/C/D/E/F는 디렉토리 구조 /A/B/C/D/E/F와 일치해야 합니다. 이 디렉토리 구조도 마찬가지입니다. 계층적?

PSR4 표준

2013년 말 다섯 번째 사양인 PSR-4가 출시되었습니다.

PSR-4는 클래스 정의를 자동으로 로드하기 위해 파일 경로를 지정하는 방법을 표준화하고 자동으로 로드되는 파일의 위치도 표준화합니다. 언뜻 보면 PSR-0과 유사해 보이지만 실제로는 기능이 일부 중복됩니다. 차이점은 PSR-4 사양이 상대적으로 깨끗하여 이전 버전의 PHP 5.3과 호환되는 콘텐츠를 제거하고 약간 PSR-0의 업그레이드 버전처럼 느껴진다는 것입니다. 물론 PSR-4는 PSR-0을 완전히 대체하기 위한 것이 아니라 필요할 때 PSR-0을 보완하기 위한 것입니다. 물론 원하는 경우 PSR-4가 PSR-0을 대체할 수도 있습니다. PSR-4는 PSR-0을 포함한 다른 자동 로딩 메커니즘과 함께 사용할 수 있습니다.

PSR4 표준과 PSR0 표준의 차이점:

  1. 在类名中使用下划线没有任何特殊含义。

  2. 命名空间与文件目录的映射方法有所调整。

对第二项我们详细解释一下 ( Composer自动加载的原理):
假如我们有一个命名空间:Foo/class,Foo 是顶级命名空间,其存在着用户定义的与目录的映射关系:

<span style="font-size: 16px;">"Foo/" => "src/"<br/></span>
로그인 후 복사

按照PSR0标准,映射后的文件目录是: src/Foo/class.php,但是按照 PSR4 标准,映射后的文件目录就会是:src/class.php,为什么要这么更改呢?原因就是怕命名空间太长导致目录层次太深,使得命名空间和文件目录的映射关系更加灵活。

再举一个例子,来源 PSR-4——新鲜出炉的PHP规范:
PSR-0风格

<span style="font-size: 16px;">    vendor/<br/>    vendor_name/<br/>        package_name/<br/>            src/<br/>                Vendor_Name/<br/>                    Package_Name/<br/>                        ClassName.php       # Vendor_Name\Package_Name\ClassName<br/>            tests/<br/>                Vendor_Name/<br/>                    Package_Name/<br/>                        ClassNameTest.php   # Vendor_Name\Package_Name\ClassName<br/></span>
로그인 후 복사

  PSR-4风格

<span style="font-size: 16px;">    vendor/<br/>    vendor_name/<br/>        package_name/<br/>            src/<br/>                ClassName.php       # Vendor_Name\Package_Name\ClassName<br/>            tests/<br/>                ClassNameTest.php   # Vendor_Name\Package_Name\ClassNameTest<br/></span>
로그인 후 복사

对比以上两种结构,明显可以看出PSR-4带来更简洁的文件结构。

위 내용은 PHP의 자동 로딩 기능에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿