Php bao gồm nhiều tệp

Chúng ta đều biết PHP là ngôn ngữ kịch bản, nghĩa là trong quá trình thực thi một ứng dụng PHP, sẽ không có bước biên dịch cái mã nguồn PHP sang a,b,c,x,y,z gì cả. Thay vào đó, chúng ta sẽ có một trình thông dịch nó sẽ đọc qua cái mã nguồn PHP của chúng ta từ trên xuống và thực thi các dòng lệnh

Giả sử ta có một đoạn mã chứa hàm do người dùng định nghĩa như sau, đặt trong tệp



require './Person.class.php';

$person = new Person();
$person->setName('You');
echo 'Hello, ' . $person->getName();
2



function sayHelloWorld()
{
    echo 'Hello, world!';
}

sayHelloWorld();

Để chạy nó, ta đơn giản chỉ định cho trình thông dịch của php thực thi tệp này

$ php index.php

1. 2 Mã trong nhiều tệp

Việc đặt tất cả mã trong một tệp sẽ làm cho tệp ngày càng dài hơn và tới một mức độ sẽ rất khó để duy trì cũng như quy mô. Việc chia nhỏ mã nguồn ra thành nhiều tệp trở thành một nhu cầu tất yếu. Tính năng PHP đã phát triển để hỗ trợ chia nhỏ công việc này

1. 2. 1. bao gồm

sau khi được bao gồm, tất cả các hàm và lớp được xác định trong tệp được bao gồm đều có phạm vi toàn cầu

With include, ví dụ bên trên sẽ được viết lại như sau

//common.php


function sayHelloWorld()
{
   echo 'Hello, world!';
}

//index.php


include './common.php'

sayHelloWorld();

1. 2. 2 yêu cầu



require './Person.class.php';

$person = new Person();
$person->setName('You');
echo 'Hello, ' . $person->getName();
3 thì cũng cho ta tính năng giống gương như


require './Person.class.php';

$person = new Person();
$person->setName('You');
echo 'Hello, ' . $person->getName();
4, khác là với yêu cầu, nếu như ta yêu cầu một tệp mà nó không tồn tại, thì ứng dụng sẽ được tiếp tục, trong khi bao gồm, ứng dụng sẽ vẫn chạy tiếp, nếu
Php bao gồm nhiều tệp

1. 2. 3 yêu cầu_một lần & bao gồm_một lần



require './Person.class.php';

$person = new Person();
$person->setName('You');
echo 'Hello, ' . $person->getName();
5 và


require './Person.class.php';

$person = new Person();
$person->setName('You');
echo 'Hello, ' . $person->getName();
6 cũng tương tự như


require './Person.class.php';

$person = new Person();
$person->setName('You');
echo 'Hello, ' . $person->getName();
4 và


require './Person.class.php';

$person = new Person();
$person->setName('You');
echo 'Hello, ' . $person->getName();
3 ở trên, chỉ khác là nếu tệp đã được yêu cầu/bao gồm rồi, thì nó sẽ không yêu cầu/bao gồm nữa

2. Tự động tải bằng PHP gốc

Giả sử ta có một ứng dụng với 2 mã tệp như thế này

//Person.class.php


class Person
{
    public $name = '';

    function getName()
    {
        return $this->name;
    }
    function setName($newName)
    {
        $this->name = $newName;
    }
}

Ta sử dụng nó trong tệp



require './Person.class.php';

$person = new Person();
$person->setName('You');
echo 'Hello, ' . $person->getName();
2



require './Person.class.php';

$person = new Person();
$person->setName('You');
echo 'Hello, ' . $person->getName();

Mọi thứ trong đó vẫn rất sạch sẽ, nhưng hãy thử các đối tượng, chúng ta có khoảng vài chục lớp cần sử dụng, tất cả những thứ này đều đồng nghĩa, là một danh sách yêu cầu rất dài ở mỗi tệp đầu, kiểu như rách



require './Person.class.php';
require './Car.class.php';
require './House.class.php';
require './Party.class.php';
require './Event.class.php';
require './Dog.class.php';
require './Cat.class.php';
require './Ball.class.php';
require './Park.class.php';
require './Sport.class.php';
require './Friend.class.php';
require './School.class.php';
require './Hospital.class.php';
.
.
.

Về mặt lý thuyết thì nó không sai, chỉ là mọi người vẫn tự hỏi là có cách nào rút gọn mà vẫn đạt được cùng một kết quả không?

2. 1 spl_autoload_register

Tính năng mà chức năng này hỗ trợ, rất rõ ràng và đơn giản. Mỗi khi một lớp được sử dụng trong tệp, và trình dịch thất bại trong quá trình tìm kiếm định nghĩa của lớp, nó sẽ gọi cái spl_autoload_register này, để thử thêm một lần nữa

Ví dụ bên trên của chúng tôi sẽ được viết lại như sau



function my_autoloader($class) {
    require $class . '.class.php';
}
spl_autoload_register('my_autoloader');

$person = new Person();
$person->setName('You');
echo 'Hello, ' . $person->getName();

Đoạn mã bên trên được đọc như sau, nếu không tìm thấy lớp Người, thì hãy thử yêu cầu tệp có tên là tên của lớp Người cộng với hậu tố



require './Person.class.php';
require './Car.class.php';
require './House.class.php';
require './Party.class.php';
require './Event.class.php';
require './Dog.class.php';
require './Cat.class.php';
require './Ball.class.php';
require './Park.class.php';
require './Sport.class.php';
require './Friend.class.php';
require './School.class.php';
require './Hospital.class.php';
.
.
.
0, tương đối với tệp hiện tại

3. Trình soạn nhạc tự động tải

Thay vì phải autoloader tự động, bây giờ chúng ta sẽ sử dụng tính năng autoload do Composer cung cấp

các ví dụ dưới đây sẽ giả định là bạn đã cài đặt nhà soạn nhạc

3. 1

Bây giờ chúng ta hãy thử viết lại ví dụ ban đầu,



require './Person.class.php';
require './Car.class.php';
require './House.class.php';
require './Party.class.php';
require './Event.class.php';
require './Dog.class.php';
require './Cat.class.php';
require './Ball.class.php';
require './Park.class.php';
require './Sport.class.php';
require './Friend.class.php';
require './School.class.php';
require './Hospital.class.php';
.
.
.
1, nhưng bằng việc sử dụng nhà soạn nhạc. Sẽ vẫn là 2 tập tin quen thuộc

// common.php


function sayHelloWorld()
{
   echo 'Hello, world!';
}

And use it at file



require './Person.class.php';

$person = new Person();
$person->setName('You');
echo 'Hello, ' . $person->getName();
2



require './common.php'; //what if we remove this line?

sayHelloWorld();

Bây giờ, ta sẽ thay thế dòng



require './Person.class.php';
require './Car.class.php';
require './House.class.php';
require './Party.class.php';
require './Event.class.php';
require './Dog.class.php';
require './Cat.class.php';
require './Ball.class.php';
require './Park.class.php';
require './Sport.class.php';
require './Friend.class.php';
require './School.class.php';
require './Hospital.class.php';
.
.
.
3 bằng một thứ khác. Đầu tiên, hãy tạo một tệp


require './Person.class.php';
require './Car.class.php';
require './House.class.php';
require './Party.class.php';
require './Event.class.php';
require './Dog.class.php';
require './Cat.class.php';
require './Ball.class.php';
require './Park.class.php';
require './Sport.class.php';
require './Friend.class.php';
require './School.class.php';
require './Hospital.class.php';
.
.
.
4 với nội dung như sau

$ php index.php
0

Sau đó, chạy câu lệnh

$ php index.php
1

Lúc này, ta sẽ nhận được một thư mục



require './Person.class.php';
require './Car.class.php';
require './House.class.php';
require './Party.class.php';
require './Event.class.php';
require './Dog.class.php';
require './Cat.class.php';
require './Ball.class.php';
require './Park.class.php';
require './Sport.class.php';
require './Friend.class.php';
require './School.class.php';
require './Hospital.class.php';
.
.
.
5 có cấu trúc như sau

$ php index.php
2

Do chúng ta đang sử dụng tính năng autoload file, nên chúng ta sẽ chỉ quan tâm đến file



require './Person.class.php';
require './Car.class.php';
require './House.class.php';
require './Party.class.php';
require './Event.class.php';
require './Dog.class.php';
require './Cat.class.php';
require './Ball.class.php';
require './Park.class.php';
require './Sport.class.php';
require './Friend.class.php';
require './School.class.php';
require './Hospital.class.php';
.
.
.
6, thử mở ra xem có gì trong đó

$ php index.php
3

Ta sẽ thấy một cái gì đó đại khái là có đường dẫn đi tới tập tin



require './Person.class.php';
require './Car.class.php';
require './House.class.php';
require './Party.class.php';
require './Event.class.php';
require './Dog.class.php';
require './Cat.class.php';
require './Ball.class.php';
require './Park.class.php';
require './Sport.class.php';
require './Friend.class.php';
require './School.class.php';
require './Hospital.class.php';
.
.
.
7. Bây giờ, để sử dụng, ta sẽ cập nhật lại nội dung của tệp


require './Person.class.php';

$person = new Person();
$person->setName('You');
echo 'Hello, ' . $person->getName();
2 như sau

$ php index.php
4

Giờ thì chạy



require './Person.class.php';
require './Car.class.php';
require './House.class.php';
require './Party.class.php';
require './Event.class.php';
require './Dog.class.php';
require './Cat.class.php';
require './Ball.class.php';
require './Park.class.php';
require './Sport.class.php';
require './Friend.class.php';
require './School.class.php';
require './Hospital.class.php';
.
.
.
9 cũng sẽ cho ta kết quả tương tự

Ta sẽ tự hỏi là nó có gì khác so với cách làm trước? . (mỗi tập tin cần cập nhật



require './Person.class.php';
require './Car.class.php';
require './House.class.php';
require './Party.class.php';
require './Event.class.php';
require './Dog.class.php';
require './Cat.class.php';
require './Ball.class.php';
require './Park.class.php';
require './Sport.class.php';
require './Friend.class.php';
require './School.class.php';
require './Hospital.class.php';
.
.
.
4 sẽ phải chạy lại câu lệnh


function my_autoloader($class) {
    require $class . '.class.php';
}
spl_autoload_register('my_autoloader');

$person = new Person();
$person->setName('You');
echo 'Hello, ' . $person->getName();
3)

3. 2

Để demo cho tính năng autoload class này, đầu tiên ta cần chuẩn bị sẵn một folder classes, trong đó có file Person. php with content code tương tự như ví dụ ở trên

$ php index.php
5

Sau đó, chúng ta sẽ cập nhật lại file



require './Person.class.php';
require './Car.class.php';
require './House.class.php';
require './Party.class.php';
require './Event.class.php';
require './Dog.class.php';
require './Cat.class.php';
require './Ball.class.php';
require './Park.class.php';
require './Sport.class.php';
require './Friend.class.php';
require './School.class.php';
require './Hospital.class.php';
.
.
.
4 như sau

$ php index.php
6

Sau đó, chạy câu lệnh



function my_autoloader($class) {
    require $class . '.class.php';
}
spl_autoload_register('my_autoloader');

$person = new Person();
$person->setName('You');
echo 'Hello, ' . $person->getName();
5, lúc này ta mở file


function my_autoloader($class) {
    require $class . '.class.php';
}
spl_autoload_register('my_autoloader');

$person = new Person();
$person->setName('You');
echo 'Hello, ' . $person->getName();
6 xem có gì trong đó

$ php index.php
7

Ta lại thấy thứ đó, đại loại là đường dẫn đi tới tệp Người. php

Bây giờ chúng ta hãy thử sử dụng class Person đó, một điều thú vị là ta không cần phải động gì đến chỗ yêu cầu, cứ việc sử dụng class Person thôi, mọi thứ đã có nhà soạn nhạc lo

$ php index.php
8

Tới đây, sau khi chạy



require './Person.class.php';
require './Car.class.php';
require './House.class.php';
require './Party.class.php';
require './Event.class.php';
require './Dog.class.php';
require './Cat.class.php';
require './Ball.class.php';
require './Park.class.php';
require './Sport.class.php';
require './Friend.class.php';
require './School.class.php';
require './Hospital.class.php';
.
.
.
9, ta sẽ vẫn nhận được kết quả tương tự

3. 3

PSR-4 là cách được khuyến nghị vì nó dễ sử dụng hơn (không cần tạo lại trình tải tự động khi bạn thêm lớp)

Sử dụng cái psr-4 này, thì mỗi lớp thêm một lần, ta sẽ không cần phải chạy lại câu lệnh



function my_autoloader($class) {
    require $class . '.class.php';
}
spl_autoload_register('my_autoloader');

$person = new Person();
$person->setName('You');
echo 'Hello, ' . $person->getName();
5

Đây cũng chính là nội dung chính của bài viết lần này, có thể được coi là trạng thái nghệ thuật của php autoload. Ok, giờ chúng ta bắt đầu trải nghiệm thử nghiệm tính năng này. Cập nhật lại file



require './Person.class.php';
require './Car.class.php';
require './House.class.php';
require './Party.class.php';
require './Event.class.php';
require './Dog.class.php';
require './Cat.class.php';
require './Ball.class.php';
require './Park.class.php';
require './Sport.class.php';
require './Friend.class.php';
require './School.class.php';
require './Hospital.class.php';
.
.
.
4 có nội dung như sau. (cập nhật xong thì chạy


function my_autoloader($class) {
    require $class . '.class.php';
}
spl_autoload_register('my_autoloader');

$person = new Person();
$person->setName('You');
echo 'Hello, ' . $person->getName();
5)

$ php index.php
9

Tạo thư mục app, trong thư mục app sẽ tạo thư mục Models và trong thư mục Models sẽ tạo file Person. php

//common.php


function sayHelloWorld()
{
   echo 'Hello, world!';
}

0

Content of file Person. php could Rút gọn như sau

//common.php


function sayHelloWorld()
{
   echo 'Hello, world!';
}

1

Trong file index. php, ta try to use it

//common.php


function sayHelloWorld()
{
   echo 'Hello, world!';
}

2

Tới đây, mọi thứ vẫn như cũ, chỉ khác một điều, là giờ ta thử tạo thêm thư mục và tệp, thì không cần phải chạy lại câu lệnh



function my_autoloader($class) {
    require $class . '.class.php';
}
spl_autoload_register('my_autoloader');

$person = new Person();
$person->setName('You');
echo 'Hello, ' . $person->getName();
5, việc ta cần làm, là thư mục theo một quy tắc