Hướng dẫn include autoload php - bao gồm php autoload

Trong bài viết lần này, chúng ta sẽ cùng nhau tìm hiểu về autoload trong PHP.

1. Modules in PHP

1.1 Code in one file

Chúng ta đều biết PHP là scripting language, nghĩa là trong quá trình thực thi một ứng dụng PHP, sẽ không có bước compile cái sourcecode PHP sang thành a,b,c,x,y,z gì cả. Thay vào đó, chúng ta sẽ một intepreter nó sẽ đọc qua cái sourcecode PHP của chúng ta từ trên xuống và thực thi các dòng lệnh.compile cái sourcecode PHP sang thành a,b,c,x,y,z gì cả. Thay vào đó, chúng ta sẽ một intepreter nó sẽ đọc qua cái sourcecode 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 code chứa một user-defined function như sau, đặt trong file

//common.php


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

6:



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

sayHelloWorld();

Để chạy nó, ta đơn giản chỉ định cho intepreter của php thực thi file này:

$ php index.php

1.2 Code in multiple files

Việc đặt tất cả code trong một file sẽ khiến file ngày càng dài, và tới một mức sẽ rất khó để maintain cũng như scale. Việc chia nhỏ sourcecode ra thành nhiều files trở thành một nhu cầu tất yếu. PHP đã phát triển tính năng để hỗ trợ việc chia nhỏ này :

1.2.1. include

...after included, all functions and classes defined in the included file have the global scope.

Với 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 require

//common.php


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

7 thì cũng cho ta tính năng giống hệt như
//common.php


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

8, khác là với require, nếu như ta require một file mà nó không tồn tại, thì ứng dụng sẽ bị ngừng lại, trong khi với include, ứng dụng sẽ vẫn chạy tiếp, nếu như nó có thể chạy tiếp
Hướng dẫn include autoload php - bao gồm php autoload

1.2.3 require_once & include_once

//common.php


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

9 và
//index.php


include './common.php'

sayHelloWorld();
0 cũng tương tự như
//common.php


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

8 và
//common.php


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

7 ở trên, chỉ khác là nếu file đã được require/include rồi, thì nó sẽ không require/include nữa.

2. Autoload in native PHP

Giả sử ta có một ứng dụng với 2 files code như 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ó ở file

//common.php


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

6



require './Person.class.php';

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

Mọi thứ trong vẫn rất clean, nhưng thử tượng tượng, chúng ta có khoảng vài chục class cần sử dụng, đều này đồng nghĩa, là một danh sách require rất dài ở mỗi đầu file, kiểu như vầ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';
.
.
.

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 ngắn gọn mà vẫn đạt được cùng một kết quả không? Câu trả lời là spl_autoload_register

2.1 spl_autoload_register

Tính năng mà function này hỗ trợ, rất clean và straightforward. Mỗi khi một class được sử dụng trong file, và intepreter thất bại trong việc tìm thấy định nghĩa của class, 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 ta 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 code bên trên được đọc như sau, nếu không tìm thấy class Person, thì hãy thử require file có tên là tên của class Person cộng với hậu tố

//index.php


include './common.php'

sayHelloWorld();
4, relative với file hiện tại.

3. Composer autoload

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

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

3.1 Autoload file

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

//index.php


include './common.php'

sayHelloWorld();
5, nhưng bằng việc sử dụng composer. Sẽ vẫn là 2 files quen thuộc:

// common.php


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

Và sử dụng nó ở file

//common.php


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

6



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

sayHelloWorld();

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

//index.php


include './common.php'

sayHelloWorld();
7 bằng một thứ khác. Đầu tiên, hãy tạo một
//index.php


include './common.php'

sayHelloWorld();
8 file với nội dung như sau:thay thế dòng
//index.php


include './common.php'

sayHelloWorld();
7 bằng một thứ khác. Đầu tiên, hãy tạo một
//index.php


include './common.php'

sayHelloWorld();
8 file 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 folder

//index.php


include './common.php'

sayHelloWorld();
9 có cấu trúc như sau:

$ php index.php
2

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

//Person.class.php


class Person
{
    public $name = '';

    function getName()
    {
        return $this->name;
    }
    function setName($newName)
    {
        $this->name = $newName;
    }
}
0, thử mở ra xem có gì trong đó nào:autoload file, nên ta sẽ chỉ quan tâm tới file
//Person.class.php


class Person
{
    public $name = '';

    function getName()
    {
        return $this->name;
    }
    function setName($newName)
    {
        $this->name = $newName;
    }
}
0, thử mở ra xem có gì trong đó nào:

$ php index.php
3

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

//Person.class.php


class Person
{
    public $name = '';

    function getName()
    {
        return $this->name;
    }
    function setName($newName)
    {
        $this->name = $newName;
    }
}
1 file. Bây giờ, để sử dụng, ta sẽ cập nhật lại nội dung của file
//common.php


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

6 như sau:

$ php index.php
4

Giờ thì chạy

//Person.class.php


class Person
{
    public $name = '';

    function getName()
    {
        return $this->name;
    }
    function setName($newName)
    {
        $this->name = $newName;
    }
}
3 cũng sẽ cho ta kết quả tương tự.

Ta sẽ tự hỏi là nó có khác gì so với cách làm trước? Về tính năng thì y hệt, nó chỉ khác là kể từ đây, mỗi khi muốn load một file mới, ta sẽ cập nhật lại file

//index.php


include './common.php'

sayHelloWorld();
8 thay vì file
//common.php


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

6. (mỗi cần cập nhật file
//index.php


include './common.php'

sayHelloWorld();
8 sẽ phải chạy lại câu lệnh
//Person.class.php


class Person
{
    public $name = '';

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

3.2 Autoload class

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

$ php index.php
5

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

//index.php


include './common.php'

sayHelloWorld();
8 như sau:

$ php index.php
6

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

//Person.class.php


class Person
{
    public $name = '';

    function getName()
    {
        return $this->name;
    }
    function setName($newName)
    {
        $this->name = $newName;
    }
}
9, lúc này, ta hãy mở file


require './Person.class.php';

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

$ php index.php
7

Ta lại thấy thứ gì đó, đại loại là đường dẫn đi tới file Person.php.

Giờ 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ì tới chỗ require, cứ việc dùng cái class Person thôi, mọi thứ đã có composer lo:

$ php index.php
8

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

//Person.class.php


class Person
{
    public $name = '';

    function getName()
    {
        return $this->name;
    }
    function setName($newName)
    {
        $this->name = $newName;
    }
}
3, ta sẽ vẫn nhận được kết quả tương tự.

3.3 PSR-4

PSR-4 is the recommended way since it offers greater ease of use (no need to regenerate the autoloader when you add classes).

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

//Person.class.php


class Person
{
    public $name = '';

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

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

//index.php


include './common.php'

sayHelloWorld();
8 có nội dung như sau: (cập nhật xong thì chạy
//Person.class.php


class Person
{
    public $name = '';

    function getName()
    {
        return $this->name;
    }
    function setName($newName)
    {
        $this->name = $newName;
    }
}
9)the state of the art của php autoload. Ok, giờ chúng ta bắt đầu trải nghiệm thử tính năng này. Cập nhật lại file
//index.php


include './common.php'

sayHelloWorld();
8 có nội dung như sau: (cập nhật xong thì chạy
//Person.class.php


class Person
{
    public $name = '';

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

$ php index.php
9

Tạo một folder app, trong folder app sẽ tạo folder Models và trong folder Models sẽ tạo file Person.phpapp, trong folder app sẽ tạo folder Models và trong folder Models sẽ tạo file Person.php

//common.php


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

0

Nội dung của file Person.php có thể rút gọn như sau:Person.php có thể rút gọn như sau:

//common.php


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

1

Trong file index.php, ta thử sử dụng nó:

//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 folder và file, thì không cần phải chạy lại câu lệnh

//Person.class.php


class Person
{
    public $name = '';

    function getName()
    {
        return $this->name;
    }
    function setName($newName)
    {
        $this->name = $newName;
    }
}
9, việc ta cần làm, là folder theo một quy tắc:

  1. Các file trong folder app phải có namespace bắt đầu bằng
    
    
    require './Person.class.php';
    
    $person = new Person();
    $person->setName('You');
    echo 'Hello, ' . $person->getName();
    
    6
  2. Tên folder chứa file phải được chỉ ra ở trên namespace, ví dụ, file nằm trong folder
    
    
    require './Person.class.php';
    
    $person = new Person();
    $person->setName('You');
    echo 'Hello, ' . $person->getName();
    
    7 thì cái namespace nó phải là
    
    
    require './Person.class.php';
    
    $person = new Person();
    $person->setName('You');
    echo 'Hello, ' . $person->getName();
    
    8.

Ví dụ, giờ ta muốn tạo Controllers, thì sẽ làm như sau:

//common.php


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

3

Nội dung file



require './Person.class.php';

$person = new Person();
$person->setName('You');
echo 'Hello, ' . $person->getName();
9 sẽ là:

//common.php


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

4

Và khi sử dụng:

//common.php


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

5

Và cứ như vậy, ta cứ tạo folder mới, file mới thoải mái, chỉ cần follow theo đúng rules thì mọi việc autoload cứ để composer lo

Hướng dẫn include autoload php - bao gồm php autoload

4. Conclusion

Ok, tới đây thì chúng ta xem như kết thúc bài viết lần này. Ngày nay thì gần như mọi framework đều follow theo psr-4 để thực hiện autoload, mà cụ thể là đều sử dụng composer. Việc hiểu được cách composer psr-4 autoload hoạt động sẽ giảm bớt cảm giá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';
.
.
.
0 khi ta code Hẹn gặp lại các bạn trong bài viết tiếp theo.
Hướng dẫn include autoload php - bao gồm php autoload
Hẹn gặp lại các bạn trong bài viết tiếp theo.