PHP Understanding

Dong Ho · about 25 mins read

Introduction

PHP: một kiểu viết tắt hồi quy của “PHP: Hypertext Preprocessor”. PHP là một ngôn ngữ lập trình kịch bản hay một loại mã lệnh chủ yếu được dùng để phát triển các ứng dụng viết cho máy chủ, mã nguồn mở, dùng cho mục đích tổng quát. Nó rất thích hợp với web và có thể dễ dàng nhúng vào trang HTML. Do được tối ưu hóa cho các ứng dụng web, tốc độ nhanh, nhỏ gọn, cú pháp giống C và Java, dễ học và thời gian xây dựng sản phẩm tương đối ngắn hơn so với các ngôn ngữ khác nên PHP đã nhanh chóng trở thành một ngôn ngữ lập trình web phổ biến nhất thế giới.

Ngôn ngữ, các thư viện, tài liệu gốc của PHP được xây dựng bởi cộng đồng và có sự đóng góp rất lớn của Zend Inc., công ty do các nhà phát triển cốt lõi của PHP lập nên nhằm tạo ra một môi trường chuyên nghiệp để đưa PHP phát triển ở quy mô doanh nghiệp.

P/s: Nguồn wiki

CGI là gì?

CGI có thể hiểu nôm na là “chuẩn gateway”. Như tên gọi của chuẩn này (Common Gateway Interface) nó mô tả cách làm việc của chuẩn CGI như sau :

  • Chỉ ra phương thức chung để truy xuất những Script, CGI cho phép bất cứ ai, không phân biệt hệ điều hành, không phân biệt trình duyệt để đều có thể gởi thông tin tới một CGI Script.
  • Ðịnh nghĩa liên kết hoặc gateway giữa Script, Server, và những chương trình khác.
  • Mô tả interface hoặc method để user có thể truy xuất Script. cho phép người tạo Web che dấu người đọc những phức tạp trong việc xử lý các dữ liệu trong trang Web.

Khi Webserver nhận yêu cầu xử lý của Client, nó sẽ đẩy cho CGI để truy xuất dữ liệu (từ form, sessions, cookies, database, file …) và xử lý, Webserver sẽ lấy output (thường là HTML) và trả về cho Client.

Xem thêm

PHP có thể làm gì?

PHP có thể làm bất cứ điều gì mà bất kỳ chương trình CGI nào khác có thể làm, chẳng hạn như thu thập dữ liệu biểu mẫu, tạo nội dung trang động hoặc gửi và nhận cookie. Nhưng PHP có thể làm nhiều hơn thế. Có ba lĩnh vực chính mà các tập lệnh PHP được sử dụng.

  • Server-side scripting: Bạn sẽ cần Web Server, trình phân tích cú pháp PHP (CGI hoặc mô đun máy chủ). Hướng dẫn cài đặt.
  • Command line scripting: Kiểu sử dụng này là lý tưởng cho các tập lệnh được thực thi thường xuyên bằng cron, task scheduler … Cách sử dụng dòng lênh với PHP
  • Viết ứng dụng máy tính để bàn (desktop applications): Không phải là lựa chọn tốt nhất để viết những ứng dụng có giao diện đồ họa, tuy nhiên bạn cũng có thể sử dụng PHP-GTK để viết desktop applications nếu bạn yêu thích PHP. Vì PHP đa nền tảng nên các ứng dụng viết ra cũng đa nền tảng theo cách này. PHP-GTK là một phần mở rộng cho PHP, không có sẵn trong bản phân phối chính. Nếu bạn quan tâm thì có thể tham khảo Building Desktop Applications in PHP with PHP-GTK

PHP đã hỗ trợ cho hầu hết các máy chủ web hiện nay, bao gồm Apache, IIS và nhiều thứ khác (bất kỳ máy chủ web nào có thể sử dụng nhị phân PHP FastCGI, như lighttpdnginx). PHP hoạt động như một mô-đun hoặc bộ xử lý CGI. Vì vậy, với PHP, bạn có quyền tự do lựa chọn một hệ điều hành và một máy chủ web. Hơn nữa, bạn cũng có thể lựa chọn sử dụng lập trình thủ tục hoặc lập trình hướng đối tượng (OOP) hoặc kết hợp cả hai.

PHP hỗ trợ làm việc với một loạt các database thông qua các cách khác nhau:

PHP hỗ trợ để giao tiếp với các service khác bằng các giao thức như LDAP, IMAP, SNMP, NNTP, POP3, HTTP, COM (trên Windows) và vô số các dịch vụ khác. Bạn cũng có thể mở “network sockets” thô để sử dụng với bất kỳ kiểu protocol nào khác.

PHP hỗ trợ xử lý văn bản và XML

Cùng với vô vàn những thứ mà PHP có thể làm được khác, xem thêm ở trang tài liệu của PHP.

PHP Core

Zend Engine

PHP Manual

Composer

Composer không quản lý package giống như NPM, YUM, APT… mà nó quản lý “packages” trên mỗi project, tải chúng về thư mục “vendor” của project. Nếu tôi muốn quản lý “global” thì sao? Xem ở đây

Để sử dụng Composer bạn sẽ cần phải có file composer.json để quản lý dependency và version dùng cho project, sau khi chạy Composer để install, bạn sẽ thấy file composer.lock, file này quan trọng và bạn cần commit nó lên project repo để các thành viên khác (và cả CI server, production server…) họ sẽ biết chính xác version nào sẽ được dùng, tránh trường hợp sau khi Comporser install xong thì thấy lỗi tùm lum.

Composer có tạo một file vendor/autoload.php. Bạn đơn giản chỉ cần include file này và bắt đầu sử dụng các class trong library mà không cần phải làm gì khác:

require __DIR__ . '/vendor/autoload.php';

$log = new Monolog\Logger('name');
$log->pushHandler(new Monolog\Handler\StreamHandler('app.log', Monolog\Logger::WARNING));
$log->addWarning('Foo');

Bạn cũng có thể thêm autoload cho mã của mình ở file composer.json

{
    "autoload": {
        "psr-4": {"Acme\\": "src/"}
    }
}

Sau khi thêm autoload ở trên bạn phải chạy lại câu lệnh sau để Composer cập nhật vendor/autoload.php

php composer.phar dump-autoload

Hoặc bạn cũng có thể autoload trong code của mình giống như thế này:

$loader = require __DIR__ . '/vendor/autoload.php';
$loader->addPsr4('Acme\\Test\\', __DIR__);

Nâng cao về autoload trên môi trường “production” (không nên làm điều này ở môi trường “develop”), xem thêm Autoloader Optimization

Xem hướng dẫn sử dụng Composer trong command line hoặc trên Composer Website

PHP frameworks

Tools

Reference

Một số thư viện & repo

Đặc điểm

  • Trong PHP, các từ khóa (ví dụ: if, other, while, echo, v.v.), các classes, functions cũng như các functions do người dùng định nghĩa sẽ không phân biệt chữ hoa chữ thường. Tuy nhiên, các tên biến thì lại có phân biệt hoa-thường.
  • Sử dụng dấu chấm phẩy (;) để kết thúc câu lệnh. String là tất cả ký tự nằm trong dấu nháy đơn hoặc nháy kép (kể cả ký tự kết thúc dòng, PHP sẽ coi kết thúc dòng là space)
  • Sử dụng dấu chấm (.) để nối chuỗi, dấu “->” để call function hoặc reference biến trong class.
  • Biến phải bắt đầu với ký tự $, tiếp đó là ký tự hoặc “underscore” (ko đc là số), ko đc chứa ký tự đặc biệt khác.
  • Có 3 phạm vi (scope) của biến:
    • GLOBAL: khai báo và sử dụng ngoài function, ko sử dụng đc bên trong function. Muốn sử dụng bên trong phải sử dụng keyword “global” (trong function), hoặc dùng trực tiếp mảng $GLOBALS['tên_biến'] (SupperGlobals)
    • LOCAL: khai báo và sử dụng bên trong function, ko sử dụng được bên ngoài function, giải phóng biến local sau khi function đã thực thi xong.
    • STATIC: là biến local được khai báo với từ khóa static để giữ biến đó không bị xóa (giải phóng) sau khi function thực thi xong.
  • echoprint được sử dụng để in ra output, print nhận 1 argument và return 1 còn echo return void nhưng nhận nhiều argurments. Để in kiểm tra kiểu dữ liệu của biến ta sử dụng var_dump($x)
  • Data Types: int(2147483647); float(2.147483647E+19); bool(true); array(3) { [0]=> string(1) “a” [1]=> int(1) [2]=> bool(true) }; object(Animal)#1 (0) { }; NULL; Resource (a database call)
  • PHP Core có sẵn rất nhiều functions để xử lý chuỗi, biến (check type), Array, Date, Directory, Filesystem, Network, Stream… PHP Reference
  • Constants (automatically global): define(name, value, boolean-case-insensitive-default-is-false)
  • Operators: === (bằng và giống type); <=> (giống compare của java, trả về -1/0/1, PHP7); $x = expr1 ?? expr2 (nếu expr1 null thì lấy expr2)
    • Logical Operators: hỗ trợ cả (and, or, &&, )
    • String Operators: $txt1 . $txt2 (nối chuỗi); $txt1 .= $txt2 (append $txt1)
    • Array Operators: $x + $y; $x == $y (same key/value pairs); $x === $y (same key/value pairs + order + types); !=; <>; !==
  • Global Variables (available in all scopes): $GLOBALS; $_SERVER; $_REQUEST; $_POST; $_GET; $_FILES; $_ENV; $_COOKIE; $_SESSION
  • Form Handling: sử dụng $_GET$_POST để lấy dữ liệu từ Client. Hãy nghĩ đến SECURITY khi người dùng tương tác
  • PHP Include Files: include 'filename'; hoặc require 'filename'; include vs. require khác nhau như thế nào? nếu file include không được tìm thấy thì include chỉ WARNING và vẫn thực thi tiếp script còn require thì sẽ stop script (ko thực thi những câu lệnh tiếp theo)
  • File Handling: Hãy cẩn thận khi xử lý file! Các lỗi thường gặp là: chỉnh sửa sai tệp, làm full ổ cứng với dữ liệu rác và xóa nội dung của tệp một cách tình cờ.
  • PHP Cookies: setcookie(name*, value, expire, path, domain, secure, httponly); Ví dụ: setcookie($cookie_name, $cookie_value, time() + (86400 * 30), "/");
  • PHP Sessions: session_start(); sau đó sử dụng $_SESSION["favcolor"] và phải session_unset() + session_destroy()
  • PHP and JSON: json_encode() để convert object to string json và json_decode() để convert string json to object

OOP

Namespaces

  • Namespaces để scope/đóng gói/bao đóng các classes (bao gồm abstractstraits), interfaces, functionsconstants. Nó giống như tên đường dẫn thư mục chứa file.
  • Namespaces không phân biệt chữ hoa chữ thường. Không được bắt đầu bằng PHP (ví dụ PHP\Classes...). Không được có dấu “\” ở đầu hoặc ở cuối.
<?php
namespace MyProject\Network;

const CONNECT_OK = 1;

class Connection { /* ... */ }
function connect() { /* ... */ }
?>

Sử dụng Namespaces giống như ta đang ở file này và refer đến một file khác, tùy vào vị trí file hiện tại và file refer mà có các cách khác nhau (đường dẫn tương đối, đường dẫn tuyệt đối).

<?php
declare(encoding='UTF-8');
namespace MyProject {

    const CONNECT_OK = 1;

    class Connection { /* ... */ }
    function connect() { /* ... */  }
    static function staticmethod() {}
}

namespace { // global code
    session_start();

    $conFunc = MyProject\connect();
    MyProject::staticmethod();
}
?>

Từ khóa “namespace” và hằng số “__NAMESPACE__

Giá trị của __NAMESPACE__ là một chuỗi chứa tên Namespace hiện tại. Là chuỗi rỗng nếu Global ko có Namespace.

/* Sử dụng __NAMESPACE__ để tạo dynamic instance */
<?php
namespace MyProject;

function get($classname)
{
    $target = __NAMESPACE__ . '\\' . $classname;
    return new $target;
}
?>
/* Sử dụng từ khóa "namespace" */
<?php
namespace MyProject; // khai báo Namespace

blah\mine(); // calls function MyProject\blah\mine()
namespace\blah\mine(); // calls function MyProject\blah\mine()

namespace\func(); // calls function MyProject\func()
namespace\sub\func(); // calls function MyProject\sub\func()
namespace\cname::method(); // calls static method "method" of class MyProject\cname
$a = new namespace\sub\cname(); // instantiates object of class MyProject\sub\cname
$b = namespace\CONSTANT_NAME; // assigns value of constant MyProject\CONSTANT_NAME to $b
?>

Aliasing/Importing với toán tử “use”

Có thể tạo 3 loại “alias” (cho “class name”, “interface name” và “namespace name”). PHP 5.6+ ta cũng có thể tạo “alias” cho “functions name” và “constants name”. Như vậy là có 5 loại “alias”.

<?php
namespace foo;
use My\Full\Classname as Another;

// this is the same as use My\Full\NSname as NSname
use My\Full\NSname;

// importing a global class
use ArrayObject;

// importing a function (PHP 5.6+)
use function My\Full\functionName;

// aliasing a function (PHP 5.6+)
use function My\Full\functionName as func;

// importing a constant (PHP 5.6+)
use const My\Full\CONSTANT_NAME;

$obj = new namespace\Another; // instantiates object of class foo\Another
$obj = new Another; // instantiates object of class My\Full\Classname
NSname\subns\func(); // calls function My\Full\NSname\subns\func
$a = new ArrayObject(array(1)); // instantiates object of class ArrayObject
// without the "use ArrayObject" we would instantiate an object of class foo\ArrayObject
func(); // calls function My\Full\functionName
echo CONSTANT; // echoes the value of My\Full\CONSTANT
?>

Importing and dynamic names

<?php
use My\Full\Classname as Another, My\Full\NSname;

$obj = new Another; // instantiates object of class My\Full\Classname
$a = 'Another';
$obj = new $a;      // instantiates object of class Another
?>

Importing and fully qualified names

<?php
use My\Full\Classname as Another, My\Full\NSname;

$obj = new Another; // instantiates object of class My\Full\Classname
$obj = new \Another; // instantiates object of class Another
$obj = new Another\thing; // instantiates object of class My\Full\Classname\thing
$obj = new \Another\thing; // instantiates object of class Another\thing
?>

Classes and Objects

Ví dụ bên dưới sẽ nói về Class, __construct và __destruct, Access Modifiers, Properties, Methods.

<?php
namespace My\App; // khai báo namespace
use My\Full\Classname as Another; // import & Alias

/* Định nghĩa class */
class Fruit {
    /**
    * Access Modifiers:
    * public - properties và methods có thể access ở mọi nơi => đây là mặc định (nếu ko có)
    * protected - properties và method có thể được access trong class và các class extends nó (lưu ý là BÊN TRONG)
    * private - CHỈ có thể sử dụng trong class
    **/

    // Properties
    public $name;
    public $color;

    /**
    * Nếu bạn tạo một hàm __construct(), PHP sẽ tự động gọi hàm này khi bạn tạo một đối tượng từ một lớp.
    * Không thể có nhiều __construct()
    **/
    function __construct($name) {
        $this->name = $name;
    }
    /**
    * Nếu bạn tạo hàm __desturation(), PHP sẽ tự động gọi hàm này ở cuối tập lệnh. Hàm này ko có đối số.
    **/
    function __destruct() {
        echo "The fruit is {$this->name}.";
    }

    // Methods
    function set_name($name) {
        $this->name = $name; // Từ khóa '$this' đề cập đến đối tượng hiện tại và chỉ có sẵn trong các phương thức.
    }
    function get_name() {
        return $this->name;
    }
    function set_color($color) {
        $this->color = $color;
    }
    function get_color() {
        return $this->color;
    }
}

$apple = new Fruit(null); // __construct() ở trên yêu cầu truyền tham số
$apple->set_name('Apple');
$apple->set_color('Red');
echo "Name: " . $apple->get_name();
echo "<br>";
echo "Color: " .  $apple->get_color();
echo "<br>";
var_dump($apple instanceof Fruit); // Sử dụng "instanceof" để kiểm tra xem một đối tượng có thuộc về một lớp cụ thể không
?>

Inheritance

Lớp con sẽ kế thừa tất cả các thuộc tính và phương thức publicprotected từ lớp cha. Ngoài ra, nó có thể có các thuộc tính và phương thức riêng.

class Fruit {
  public $name;
  public $color;
  public function __construct($name, $color) {
    $this->name = $name;
    $this->color = $color;
  }
  public function intro() {
    echo "The fruit is {$this->name} and the color is {$this->color}.";
  }
}

// Strawberry is inherited from Fruit
class Strawberry extends Fruit {
  public function message() {
    echo "Am I a fruit or a berry? ";
  }
}
$strawberry = new Strawberry("Strawberry", "red");
$strawberry->message();
$strawberry->intro(); // vì đang public nên call ở đây OK, nhưng nếu là protected thì sẽ ERROR! (phải call bên trong Strawberry)

Overriding Inherited Methods

Inherited methods có thể ghi đè các methods và contrutor ở child class.

Từ khóa “final”

Từ khóa final có thể được sử dụng để ngăn chặn kế thừa lớp (nếu dùng cho class) hoặc để ngăn chặn Overriding method (nếu dùng cho method).

final class Fruit {
  // some code
}

// will result in error
class Strawberry extends Fruit {
  // some code
}

/*************************************/

class Fruit {
  final public function intro() {
    // some code
  }
}

class Strawberry extends Fruit {
  // will result in error
  public function intro() {
    // some code
  }
}

Class Constants

Sử dụng từ khóa const để khai báo một constant. Sử dụng bằng Class::CONST_NAME hoặc self::CONST_NAME (sử dụng trong class)

class Goodbye {
  const LEAVING_MESSAGE = "Thank you for visiting!";
  public function byebye() {
    echo self::LEAVING_MESSAGE;
  }
}

$goodbye = new Goodbye();
$goodbye->byebye();
echo "<br>-------<br>";
echo Goodbye::LEAVING_MESSAGE;

Abstract Classes

<?php
abstract class ParentClass {
  abstract public function someMethod1();
  abstract public function someMethod2($name, $color);
  abstract public function someMethod3() : string;
}
?>
// Parent class
abstract class Car {
  public $name;
  public function __construct($name) {
    $this->name = $name;
  }
  abstract public function intro() : string;
}

// Child classes
class Audi extends Car {
  public function intro() : string {
    return "Choose German quality! I'm an $this->name!";
  }
}
abstract class ParentClass {
  // Abstract method with an argument
  abstract protected function prefixName($name);
}

class ChildClass extends ParentClass {
  // The child class may define optional arguments that are not in the parent's abstract method
  public function prefixName($name, $separator = ".", $greet = "Dear") {
    if ($name == "John Doe") {
      $prefix = "Mr";
    } elseif ($name == "Jane Doe") {
      $prefix = "Mrs";
    } else {
      $prefix = "";
    }
    return "{$greet} {$prefix}{$separator} {$name}";
  }
}

What are Traits?

PHP chỉ hỗ trợ đơn kế thừa (một lớp con chỉ có thể kế thừa từ một cha mẹ duy nhất). Muốn “đa kế thừa” thì sử dụng “Traits”. Lưu ý: privateprotected access modifier chỉ có thể call bên trong hàm “kế thừa” (sử dụng Traits). CALL: $this->privateFunction()

/**
* sử dụng từ khóa "trait" để định nghĩa một Trait
**/
trait TraitClass1 {
  public function func11() { echo 'func11() <br>'; }
  protected function func12() { echo 'func12() <br>'; }
}
trait TraitClass2 {
  private function privateFunc() { echo 'privateFunc() <br>'; }
}

/**
* sử dụng từ khóa "use" để sử dụng Trait trong một class
**/
class ChildClass1 {
  use TraitClass1; // extends (use) TraitClass1 để sử dụng func11 & func12
}

class ChildClass2 {
  use TraitClass1, TraitClass2; // có thể extend (use) cả 2 Traits để sử dụng func11, func22 và privateFunc

  public function check() {
    $this -> privateFunc();
  }
}

$child1 = new ChildClass1();
$child1->func11(); // OK vì public
$child1->func12(); // Error vì protected
echo '<p>~~~~~~~~~~~~~~~~~~~~~~</p>';
$child2 = new ChildClass2();
$child2->func11(); // OK vì public
$child2->func12(); // Error vì protected
$child2->privateFunc(); // Error vì private
$child2->check(); // OK vì private nhưng đc call trong check() của ChildClass2

Static Methods & Properties

class Hi {
  public static function getName() {
    return "My Name"; // vì return value nên phải echo value đó ra
  }
}
class greeting extends Hi {
  public static $value = 3.14159; // một static property
  public static function welcome() { // một static function
    echo "Hello World!";
    echo parent::getName(); // sử dụng từ khóa "parent" để caal hàm static của class cha
  }
  public function __construct() {
    self::welcome(); // sử dụng từ khóa "self"
  }
}

// Call static method
GrEeTiNg::welcome(); // namespace không phân biệt hoa-thường
// Get static property
echo greeting::$value; // MORE: self::$value; parent::$value;
Xem thêm các bài viết khác cùng chủ đề
Outline

history cached

play_arrow arrow_right_alt

update skip_next

create close

settings arrow_downward

×

Memo

...
×

Under Maintenance