>  기사  >  PHP 프레임워크  >  Laravel에서 일반적으로 사용되는 PHP 구문을 요약합니다.

Laravel에서 일반적으로 사용되는 PHP 구문을 요약합니다.

藏色散人
藏色散人앞으로
2021-09-09 11:28:262145검색

머리말

Laravel 프레임워크컴포넌트화된 디자인과 디자인 패턴의 적절한 사용으로 인해 프레임워크 자체가 간단하고 확장이 쉽습니다. ThinkPHP의 통합 함수 프레임워크(모든 함수가 사용되거나 없음)와 달리 Laravel은 작성 도구를 사용하여 패키지를 관리합니다. 함수를 추가하려는 경우 구성 요소를 직접 추가할 수 있습니다. 예를 들어, 크롤러를 작성하고 페이지 컬렉션 컴포넌트를 사용하는 경우: composer require jaeger/querylistcomposer require jaeger/querylist

本文简要介绍 Laravel 中频繁用到的 PHP 特性与新语法,具体可参考。

组件化开发

Laravel 进行组件化开发,得益于遵循 PSR-4 规范的 composer 工具,其利用命名空间和自动加载来组织项目文件。更多参考:composer 自动加载机制

命名空间

命名冲突

在团队协作、引入第三方依赖代码时,往往可能会出现类、函数和接口重名的情况。比如:

<?php     
# google.php
class User 
{
    private $name;
}
<?php     
# mine.php
// 引入第三方依赖
include &#39;google.php&#39;;

class User
{
    private $name;
}

$user = new User();    // 命名冲突

因为同时定义了类 User 导致命名冲突:

Laravel에서 일반적으로 사용되는 PHP 구문을 요약합니다.

解决办法

从 PHP 5.3 开始引入,参考 PHP 手册 能知道命名空间有 2 个作用:避免命名冲突、保持命名简短。比如使用命名空间后:

<?php # google.php
namespace Google;

// 模拟第三方依赖
class User {
    private $name = &#39;google&#39;;

    public function getName() {
        echo $this->name . PHP_EOL;
    }
}
<?php # mine.php
namespace Mine;

// 导入并命名别名
use Google as G;

// 导入文件使得 google.php 命名空间变为 mine.php 的子命名空间
include &#39;google.php&#39;;

/* 避免了命名冲突 */
class User
{
    private $name = &#39;mine&#39;;

    public function getName() {
        echo $this->name . PHP_EOL;
    }
}

/* 保持了命名简短 */
// 如果没有命名空间,为了类名也不冲突,可能会出现这种函数名
// $user = new Google_User();
// Zend 风格并不提倡
$user = new G\User();

// 为了函数名也不冲突,可能会出现这种函数名
// $user->google_get_name()
$user->getName();

$user = new User();
$user->getName();

运行:

$ php demo.php
google
mine

PSR 规范

其实 namespace 与文件名无关,但按 PSR 标准要求:命名空间与文件路径一致 & 文件名与类名一致。比如 Laravel 默认生成的 laravel-demo/app/Http/Controllers/Auth/LoginController.php,其命名空间为 AppHttpControllersAuth & 类名为 LoginController

遵循规范,上边的 mine.phpgoogle.php 都应叫 User.php

namespace 操作符与__NAMESPACE__ 魔术常量

...
// $user = new User();
$user = new namespace\User();    // 值为当前命名空间
$user->getName();

echo __NAMESPACE__ . PHP_EOL;    // 直接获取当前命名空间字符串    // 输出 Mine

三种命名空间的导入

<?php namespace CurrentNameSpace;

// 不包含前缀
$user = new User();        # CurrentNameSpace\User();

// 指定前缀
$user = new Google\User();    # CurrentNameSpace\Google\User();

// 根前缀
$user = new \Google\User();    # \Google\User();

全局命名空间

如果引用的类、函数没有指定命名空间,则会默认在当在 __NAMESPACE__下寻找。若要引用全局类:

<?php namespace Demo;

// 均不会被使用到
function strlen() {}
const INI_ALL = 3;
class Exception {}

$a = \strlen(&#39;hi&#39;);         // 调用全局函数 strlen
$b = \CREDITS_GROUP;          // 访问全局常量 CREDITS_GROUP
$c = new \Exception(&#39;error&#39;);   // 实例化全局类 Exception

多重导入与多个命名空间

// use 可一次导入多个命名空间
use Google,
    Microsoft;

// 良好实践:每行一个 use
use Google;
use Microsoft;
<?php // 一个文件可定义多个命名空间
namespace Google {
    class User {}
}    
    
namespace Microsoft {
    class User {}
}   

// 良好实践:“一个文件一个类”

导入常量、函数

从 PHP 5.6 开始,可使用 use functionuse const 分别导入函数和常量使用:

# google.php
const CEO = 'Sundar Pichai';
function getMarketValue() {
    echo '770 billion dollars' . PHP_EOL;
}
# mine.php
use function Google\getMarketValue as thirdMarketValue;
use const Google\CEO as third_CEO;

thirdMarketValue();
echo third_CEO;

运行:

$ php mine.php
google
770 billion dollars
Sundar Pichaimine
Mine

文件包含

手动加载

使用 includerequire 引入指定的文件,(字面理解)需注意 require 出错会报编译错误中断脚本运行,而 include 出错只会报 warning 脚本继续运行。

include 文件时,会先去 php.ini 中配置项 include_path 指定的目录找,找不到才在当前目录下找:

Laravel에서 일반적으로 사용되는 PHP 구문을 요약합니다.

<?php     
// 引入的是 /usr/share/php/System.php
include &#39;System.php&#39;;

自动加载

void __autoload(string $class )  能进行类的自动加载,但一般都使用 spl_autoload_register 手动进行注册:

<?php // 自动加载子目录 classes 下 *.class.php 的类定义
function __autoload($class) {
    include &#39;classes/&#39; . $class . &#39;.class.php&#39;;
}

// PHP 5.3 后直接使用匿名函数注册
$throw = true;        // 注册出错时是否抛出异常
$prepend = false;    // 是否将当前注册函数添加到队列头

spl_autoload_register(function ($class) {
    include &#39;classes/&#39; . $class . &#39;.class.php&#39;;
}, $throw, $prepend);

在 composer 生成的自动加载文件 laravel-demo/vendor/composer/autoload_real.php  中可看到:

class ComposerAutoloaderInit8b41a
{
    private static $loader;

    public static function loadClassLoader($class)
    {
        if ('Composer\Autoload\ClassLoader' === $class) {
            // 加载当前目录下文件
            require __DIR__ . '/ClassLoader.php';
        }
    }
    
     public static function getLoader()
    {
        if (null !== self::$loader) {
            return self::$loader;
        }
    
        // 注册自己的加载器
        spl_autoload_register(array('ComposerAutoloaderInit8b41a6', 'loadClassLoader'), true, true);
        self::$loader = $loader = new \Composer\Autoload\ClassLoader();
        spl_autoload_unregister(array('ComposerAutoloaderInit8b41a6a', 'loadClassLoader'));

        ...
     }
 
    ...
}

这里只提一下,具体 Laravel 整体是怎么做自动加载的,后边的文章会细说。

反射

参考 PHP 手册,可简单的理解为在运行时获取对象的完整信息。反射有 5 个类:

ReflectionClass     // 解析类名
ReflectionProperty     // 获取和设置类属性的信息(属性名和值、注释、访问权限)
ReflectionMethod     // 获取和设置类函数的信息(函数名、注释、访问权限)、执行函数等
ReflectionParameter    // 获取函数的参数信息
ReflectionFunction    // 获取函数信息

比如 ReflectionClass 的使用:

<?php class User
{
    public $name;
    public $age;

    public function __construct($name = &#39;Laruence&#39;, $age = 35) {
        $this->name = $name;
        $this->age  = $age;
    }

    public function intro() {
        echo '[name]: ' . $this->name . PHP_EOL;
        echo '[age]: '  . $this->age  . PHP_EOL;
    }
}

reflect('User');

// ReflectionClass 反射类使用示例
function reflect($class) {
    try {
        $ref = new ReflectionClass($class);
        // 检查是否可实例化
        // interface、abstract class、 __construct() 为 private 的类均不可实例化
        if (!$ref->isInstantiable()) {
            echo "[can't instantiable]: ${class}\n";
        }

        // 输出属性列表
        // 还能获取方法列表、静态常量等信息,具体参考手册
        foreach ($ref->getProperties() as $attr) {
            echo $attr->getName() . PHP_EOL;
        }

        // 直接调用类中的方法,个人认为这是反射最好用的地方
        $obj = $ref->newInstanceArgs();
        $obj->intro();
    } catch (ReflectionException $e) {
            // try catch 机制真的不优雅
            // 相比之下 Golang 的错误处理虽然繁琐,但很简洁
        echo '[reflection exception: ]' . $e->getMessage();
    }
}

运行:

$ php reflect.php
name
age
[name]: Laruence
[age]: 35

其余 4 个反射类参考手册 demo 即可。

后期静态绑定

参考 PHP 手册,先看一个例子:

<?php class Base
{
        // 后期绑定不局限于 static 方法
    public static function call() {
        echo &#39;[called]: &#39; . __CLASS__ . PHP_EOL;
    }

    public static function test() {
        self::call();        // self   取值为 Base  直接调用本类中的函数
        static::call();        // static 取值为 Child 调用者
    }
}

class Child extends Base
{
    public static function call() {
        echo &#39;[called]: &#39; . __CLASS__ . PHP_EOL;
    }
}


Child::test();

输出:

$ php late_static_bind.php
[called]: Base
[called]: Child

在对象实例化时,self:: 会实例化根据定义所在的类,static:: 会实例化调用它的类。

trait

基本使用

参考 PHP 手册,PHP 虽然是单继承的,但从 5.4 后可通过 trait 水平组合“类”,来实现“类”的多重继承,其实就是把重复的函数拆分成 triat 放到不同的文件中,通过 use 关键字按需引入、组合。可类比 Golang 的 struct 填鸭式组合来实现继承。比如:

<?php class DemoLogger
{
    public function log($message, $level) {
        echo "[message]: $message", PHP_EOL;
        echo "[level]: $level", PHP_EOL;
    }
}

trait Loggable
{
    protected $logger;

    public function setLogger($logger) {
        $this->logger = $logger;
    }

    public function log($message, $level) {
        $this->logger->log($message, $level);
    }
}

class Foo
{
        // 直接引入 Loggable 的代码片段
    use Loggable;
}

$foo = new Foo;
$foo->setLogger(new DemoLogger);
$foo->log('trait works', 1);

运行:

$ php trait.php
[message]: trait works
[level]: 1

更多参考:我所理解的 PHP Trait

重要性质

优先级

当前类的函数会覆盖 trait 的同名函数,trait 会覆盖父类的同名函数( use trait 相当于当前类直接覆写了父类的同名函数)

trait 函数冲突

同时引入多个 trait 可用 ,

이 글에서는 Laravel에서 자주 사용되는 PHP 기능과 새로운 구문을 간략하게 소개하고 있으니 참고하시기 바랍니다. . 🎜🎜컴포넌트 기반 개발🎜🎜Laravel은 네임스페이스와 자동 로딩을 사용하여 프로젝트 파일을 구성하는 PSR-4 사양을 따르는 작성기 도구 덕분에 컴포넌트 기반 개발을 수행합니다. 추가 참조: Composer 자동 로딩 메커니즘🎜

네임스페이스

이름 충돌

🎜팀 협업 및 타사 종속 코드 도입 시 클래스, 함수 및 인터페이스의 중복 이름이 종종 발생할 수 있습니다. 예: 🎜
<?php trait Apple
{
    public function getCEO() {
        echo &#39;[Apple CEO]: Tim Cook&#39;, PHP_EOL;
    }

    public function getMarketValue() {
        echo &#39;[Apple Market Value]: 953 billion&#39;, PHP_EOL;
    }
}


trait MicroSoft
{
    public function getCEO() {
        echo &#39;[MicroSoft CEO]: Satya Nadella&#39;, PHP_EOL;
    }

    public function getMarketValue() {
        echo &#39;[MicroSoft Market Value]: 780 billion&#39;, PHP_EOL;
    }

    abstract public function MadeGreatOS();

    static public function staticFunc() {
        echo &#39;[MicroSoft Static Function]&#39;, PHP_EOL;
    }

    public function staticValue() {
        static $v;
        $v++;
        echo &#39;[MicroSoft Static Value]: &#39; . $v, PHP_EOL;
    }
}


// Apple 最终登顶,成为第一家市值超万亿美元的企业
trait Top
{
    // 处理引入的 trait 之间的冲突
    use Apple, MicroSoft {
        Apple::getCEO insteadof MicroSoft;
        Apple::getMarketValue insteadof MicroSoft;
    }
}


class Linux
{
    use Top {
            // as 关键字可以重命名函数、修改权限控制
        getCEO as private noCEO;
    }

    // 引入后必须实现抽象方法
    public function MadeGreatOS() {
        echo &#39;[Linux Already Made]&#39;, PHP_EOL;
    }

    public function getMarketValue() {
        echo &#39;[Linux Market Value]: Infinity&#39;, PHP_EOL;
    }
}

$linux = new Linux();
// 和 extends 继承一样
// 当前类中的同名函数也会覆盖 trait 中的函数
$linux->getMarketValue();

// trait 中可以定义静态方法
$linux::staticFunc();

// 在 trait Top 中已解决过冲突,输出库克
$linux->getCEO();
// $linux->noCEO();        // Uncaught Error: Call to private method Linux::noCEO() 

// trait 中可以定义静态变量
$linux->staticValue();
$linux->staticValue();
$ php trait.php
[Linux Market Value]: Infinity
[MicroSoft Static Function]
[Apple CEO]: Tim Cook
[MicroSoft Static Value]: 1
[MicroSoft Static Value]: 2
🎜User 클래스가 동시에 정의되므로 이름 충돌이 발생합니다. 🎜🎜Laravel에서 일반적으로 사용되는 PHP 구문을 요약합니다.🎜

솔루션

🎜PHP 5.3에서 도입됨 , 네임스페이스에 대해 알아보려면 PHP 매뉴얼을 참조하세요. 2가지 기능이 있습니다: 🎜 이름 충돌 🎜 방지, 🎜이름 짧게 유지🎜. 예를 들어 네임스페이스를 사용한 후: 🎜rrreeerrreee🎜Run: 🎜rrreee

PSR 사양

🎜사실 네임스페이스는 파일 이름과 관련이 없지만 PSR 표준 요구 사항에 따르면 네임스페이스는 일관됩니다. 파일 경로 및 파일 이름은 클래스 이름과 일치합니다. 예를 들어, Laravel이 기본적으로 생성한 laravel-demo/app/Http/Controllers/Auth/LoginController.php에는 AppHttpControllersAuth라는 네임스페이스와 LoginController code>🎜🎜사양에 따라 위의 <code>mine.phpgoogle.php는 모두 User.php🎜

네임스페이스 연산자 __NAMESPACE__ 매직 상수 사용

rrreee

세 개의 네임스페이스 가져오기

rrreee

전역 네임스페이스

🎜참조된 클래스 또는 함수가 지정하지 않은 경우 네임스페이스인 경우 기본적으로 __NAMESPACE__에서 검색됩니다. 전역 클래스를 참조하려면: 🎜rrreee

다중 가져오기 및 여러 네임스페이스

rrreeerrreee

상수 및 함수 가져오기

🎜PHP 5.6부터 함수 사용을 사용할 수 있습니다. const를 사용하여 함수와 상수를 각각 가져옵니다. 사용: 🎜rrreeerrreee🎜실행: 🎜rrreee

파일 포함

수동 로드

🎜 include 사용 또는 require는 지정된 파일을 소개합니다. (리터럴 해석) require 오류가 발생하면 컴파일 오류가 보고되고 스크립트가 중단되지만 포함 오류는 오류만 발생합니다. 경고를 보고하면 스크립트가 계속 실행됩니다. 🎜🎜파일을 포함할 때 먼저 php.ini의 include_path 구성 항목에 지정된 디렉터리에서 검색합니다. 파일을 찾을 수 없으면 현재 디렉터리에서 검색합니다: 🎜🎜Laravel에서 일반적으로 사용되는 PHP 구문을 요약합니다.🎜rrreee

자동 로딩

🎜 void __autoload(string $class)는 클래스를 자동으로 로드할 수 있지만 spl_autoload_register는 일반적으로 수동으로 등록하는 데 사용됩니다. 🎜rrreee🎜composer laravel-demo에서 생성한 자동 로딩 파일에서 /vendor/composer/autoload_real.php에서 볼 수 있습니다: 🎜rrreee🎜여기서만 언급하겠습니다. 특히 Laravel이 전체적으로 자동 로딩을 수행하는 방법은 다음 기사에서 자세히 설명합니다. 🎜🎜Reflection🎜🎜PHP 매뉴얼을 참고하세요. 이는 런타임 시 객체의 전체 정보를 얻는 것으로 간단히 이해될 수 있습니다. 리플렉션에는 5가지 클래스가 있습니다: 🎜rrreee🎜예를 들어 ReflectionClass 사용: 🎜rrreee🎜Run: 🎜rrreee🎜나머지 4개의 리플렉션 클래스는 수동 데모를 참조할 수 있습니다. 🎜🎜나중에 정적 바인딩🎜🎜PHP 매뉴얼을 참조하여 먼저 예제를 살펴보세요. 🎜rrreee🎜출력: 🎜rrreee🎜객체가 인스턴스화되면 self::는 다음에 따라 클래스를 인스턴스화합니다. 정의에 따라 static::은 이를 호출하는 클래스를 인스턴스화합니다. 🎜🎜trait🎜

기본 사용법

🎜PHP 매뉴얼을 참조하세요. PHP는 단일 상속이지만 5.4부터는 "클래스"를 특성을 통해 수평으로 결합하여 "클래스"의 다중 상속을 구현할 수 있습니다. , 반복되는 기능은 triat으로 분할되어 다른 파일에 배치되며 use 키워드를 통해 필요에 따라 도입되고 결합됩니다. 상속은 Golang의 구조체 주입 조합과 유사하게 구현될 수 있습니다. 예: 🎜rrreee🎜Run: 🎜rrreee🎜추가 참조: PHP Trait에 대해 내가 이해한 것🎜

중요 속성

Priority

🎜현재 클래스의 함수가 특성의 함수를 재정의합니다. 같은 이름의 특성은 상위 클래스의 같은 이름의 함수를 덮어씁니다(특성 사용은 현재 클래스가 상위 클래스의 같은 이름의 함수를 직접 재정의하는 것과 동일합니다)🎜특성 함수 충돌🎜여러 특성을 동시에 도입 , , 즉 다중 상속으로 구분할 수 있습니다. 🎜

多个 trait 有同名函数时,引入将发生命名冲突,使用 insteadof 来指明使用哪个 trait 的函数。

重命名与访问控制

使用 as 关键字可以重命名的 trait 中引入的函数,还可以修改其访问权限。

其他

trait 类似于类,可以定义属性、方法、抽象方法、静态方法和静态属性。

下边的苹果、微软和 Linux 的小栗子来说明:

<?php trait Apple
{
    public function getCEO() {
        echo &#39;[Apple CEO]: Tim Cook&#39;, PHP_EOL;
    }

    public function getMarketValue() {
        echo &#39;[Apple Market Value]: 953 billion&#39;, PHP_EOL;
    }
}


trait MicroSoft
{
    public function getCEO() {
        echo &#39;[MicroSoft CEO]: Satya Nadella&#39;, PHP_EOL;
    }

    public function getMarketValue() {
        echo &#39;[MicroSoft Market Value]: 780 billion&#39;, PHP_EOL;
    }

    abstract public function MadeGreatOS();

    static public function staticFunc() {
        echo &#39;[MicroSoft Static Function]&#39;, PHP_EOL;
    }

    public function staticValue() {
        static $v;
        $v++;
        echo &#39;[MicroSoft Static Value]: &#39; . $v, PHP_EOL;
    }
}


// Apple 最终登顶,成为第一家市值超万亿美元的企业
trait Top
{
    // 处理引入的 trait 之间的冲突
    use Apple, MicroSoft {
        Apple::getCEO insteadof MicroSoft;
        Apple::getMarketValue insteadof MicroSoft;
    }
}


class Linux
{
    use Top {
            // as 关键字可以重命名函数、修改权限控制
        getCEO as private noCEO;
    }

    // 引入后必须实现抽象方法
    public function MadeGreatOS() {
        echo &#39;[Linux Already Made]&#39;, PHP_EOL;
    }

    public function getMarketValue() {
        echo &#39;[Linux Market Value]: Infinity&#39;, PHP_EOL;
    }
}

$linux = new Linux();
// 和 extends 继承一样
// 当前类中的同名函数也会覆盖 trait 中的函数
$linux->getMarketValue();

// trait 中可以定义静态方法
$linux::staticFunc();

// 在 trait Top 中已解决过冲突,输出库克
$linux->getCEO();
// $linux->noCEO();        // Uncaught Error: Call to private method Linux::noCEO() 

// trait 中可以定义静态变量
$linux->staticValue();
$linux->staticValue();

运行:

$ php trait.php
[Linux Market Value]: Infinity
[MicroSoft Static Function]
[Apple CEO]: Tim Cook
[MicroSoft Static Value]: 1
[MicroSoft Static Value]: 2

总结

本节简要提及了命名空间、文件自动加载、反射机制与 trait 等,Laravel 正是恰如其分的利用了这些新特性,才实现了组件化开发、服务加载等优雅的特性。

위 내용은 Laravel에서 일반적으로 사용되는 PHP 구문을 요약합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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