目錄
My Todo-List App
首頁 後端開發 php教程 使用php搭建自己的mvc框架

使用php搭建自己的mvc框架

Nov 26, 2016 pm 04:42 PM
mvc php

一、什麼是MVC

MVC模式(Model-View-Controller)是軟體工程中的軟體架構模式,把軟體系統分成三個基本部分:模型(Model)、視圖(View)和控制器(Controller)。

MVC模式的目的是實現一種動態的程式設計,使後續對程式的修改和擴展簡化,並且使程式某一部分的重複利用成為可能。除此之外,此模式透過對複雜度的簡化,使程式結構更加直觀。軟體系統透過對自身基本部份分離的同時也賦予了各個基本部分應有的功能。專業人員可以透過自身的專長分組:

(控制器Controller)- 負責轉送請求,對請求進行處理。

(視圖View) – 介面設計人員進行圖形介面設計。

(模型Model) – 程式設計師編寫程式應有的功能(實現演算法等等)、資料庫專家進行資料管理和資料庫設計(可以實現具體的功能)。

使用php搭建自己的mvc框架

模型(Model) 「資料模型」(Model)用於封裝與應用程式的業務邏輯相關的資料以及對資料的處理方法。 「模型」有對資料直接存取的權力,例如對資料庫的存取。 “模型”不依賴“視圖”和“控制器”,也就是說,模型不關心它會被如何顯示或如何被操作。但是模型中資料的變化一般會透過一種刷新機制被公佈。為了實現這種機制,用於監視此模型的視圖必須事先在此模型上註冊,從而,視圖可以了解在資料模型上發生的變更。

視圖(View) 視圖層能夠實現資料有目的的顯示(理論上,這不是必需的)。在視圖中一般沒有程式上的邏輯。為了實現視圖上的刷新功能,視圖需要存取它監視的資料模型(Model),因此應該事先在被它監視的資料那裡註冊。

控制器(Controller) 控制器起到不同層面間的組織作用,用於控制應用程式的流程。它處理事件並作出回應。 「事件」包括使用者的行為和資料模型上的改變。

二、為什麼要自己開發MVC框架

網絡上有大量優秀的MVC框架可供使用,本教程並不是為了開發一個全面的、終極的MVC框架解決方案,而是將它看作是一個很好的從內部學習PHP的機會,在此過程中,你將學習物件導向程式設計和設計模式,並學習到開放中的一些注意事項。

更重要的是,你可以完全控制你的框架,並將你的想法融入你所發展的框架中。雖然不一定是做好的,但是你可以按照你的方式去開發功能和模組。

三、開始開發自己的MVC框架

在開始開發前,讓我們先來把專案建立好,假設我們建立的專案為todo,那麼接下來的第一步就是把目錄結構先設定好。

使用php搭建自己的mvc框架

雖然在這個教程中不會使用到上面的所有的目錄,但是為了以後程序的可拓展性,在一開始就把程序目錄設置好使非常必要的。以下就具體說說每個目錄的作用:

application – 存放程式碼

config – 存放程式設定或資料庫設定

db – 用來存放資料庫備份內容

library – 存放框架程式碼

public – 存放靜態檔案

scripts – 存放命令列工具

tmp – 存放臨時資料

在目錄設定好以後,我們接下來就要來頂一下一些程式碼的規格:

MySQL的表名需小寫並採用複數形式,如items,cars

模組名(Models)需首字母大寫,並採用單數模式,如Item,Car

控制器(Controllers)需首字母大寫,採用複數形式並在名稱中添加“Controller”,如ItemsController, CarsController

視圖(Views)採用複數形式,並在後面加上行為作為文件,如:items/view.php, cars/buy.php

上述的一些规则是为了能在程序钟更好的进行互相的调用。接下来就开始真正的编码了。

第一步将所有的的请求都重定向到public目录下,解决方案是在todo文件下添加一个.htaccesss文件,文件内容为:

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule    ^$    public/    [L]
RewriteRule    (.*) public/$1    [L]
</IfModule>
登入後複製

在我们把所有的请求都重定向到public目录下以后,我们就需要将所有的数据请求都再重定向到public下的index.php文件,于是就需要在public文件夹下也新建一个.htaccess文件,文件内容为:

<IfModule mod_rewrite.c>
RewriteEngine On
#如果文件存在就直接访问目录不进行RewriteRule
RewriteCond %{REQUEST_FILENAME} !-f
#如果目录存在就直接访问目录不进行RewriteRule
RewriteCond %{REQUEST_FILENAME} !-d
#将所有其他URL重写到 index.php/URL
RewriteRule ^(.*)$ index.php?url=$1 [PT,L]
</IfModule>
登入後複製

这么做的主要原因有:

可以使程序有一个单一的入口,将所有除静态程序以外的程序都重定向到index.php上;

可以用来生成利于SEO的URL,想要更好的配置URL,后期可能会需要URL路由,这里先不做介绍了。

做完上面的操作,就应该知道我们需要做什么了,没错!在public目录下添加index.php文件,文件内容为:

<?php
    define(&#39;DS&#39;,DIRECTORY_SEPARATOR);
    define(&#39;ROOT&#39;,dirname(dirname(__FILE__)));
    $url = $_GET[&#39;url&#39;];
    require_once(ROOT.DS.&#39;library&#39;.DS.&#39;bootstrap.php&#39;);
登入後複製

注意上面的PHP代码中,并没有添加PHP结束符号”?>”,这么做的主要原因是:对于只包含PHP代码的文件,结束标志(“?>”)最好不存在,PHP自身并不需要结束符号,不添加结束符号可以很大程度上防止末尾被添加额外的注入内容,让程序更加安全。

在index.php中,我们对library文件夹下的bootstrap.php发起了请求,那么bootstrap.php这个启动文件中到底会包含哪些内容呢?

<?php
    require_once(ROOT.DS.&#39;config&#39;.DS .&#39;config.php&#39;);
    require_once(ROOT.DS.&#39;library&#39;.DS .&#39;shared.php&#39;);
登入後複製

以上文件都可以直接在index.php文件中引用,我们这么做的原因是为了在后期管理和拓展中更加的方便,所以把需要在一开始的时候就加载运行的程序统一放到一个单独的文件中引用。

先来看看config文件下的config .php文件,该文件的主要作用是设置一些程序的配置项及数据库连接等,主要内容为:

<?php
    # 设置是否为开发状态
    define(&#39;DEVELOPMENT_ENVIRONMENT&#39;,true);
    # 设置数据库连接所需数据
    define(&#39;DB_HOST&#39;,&#39;localhost&#39;);
    define(&#39;DB_NAME&#39;,&#39;todo&#39;);
    define(&#39;DB_USER&#39;,&#39;root&#39;);
    define(&#39;DB_PASSWORD&#39;,&#39;root&#39;);
登入後複製

应该说config.php涉及到的内容并不多,不过是一些基础数据的一些设置,再来看看library下的共用文件shared.php应该怎么写。

<?php
    /* 检查是否为开发环境并设置是否记录错误日志 */
    function setReporting(){
        if (DEVELOPMENT_ENVIRONMENT == true) {
            error_reporting(E_ALL);
            ini_set(&#39;display_errors&#39;,&#39;On&#39;);
        } else {
            error_reporting(E_ALL);
            ini_set(&#39;display_errors&#39;,&#39;Off&#39;);
            ini_set(&#39;log_errors&#39;,&#39;On&#39;);
            ini_set(&#39;error_log&#39;,ROOT.DS. &#39;tmp&#39; .DS. &#39;logs&#39; .DS. &#39;error.log&#39;);
        }
    }
    /* 检测敏感字符转义(Magic Quotes)并移除他们 */
    function stripSlashDeep($value){
    $value = is_array($value) ? array_map(&#39;stripSlashDeep&#39;,$value) : stripslashes($value);
        return $value;
    }
    function removeMagicQuotes(){
        if (get_magic_quotes_gpc()) {
            $_GET = stripSlashDeep($_GET);
            $_POST = stripSlashDeep($_POST);
            $_COOKIE = stripSlashDeep($_COOKIE);
        }
    }
    /* 检测全局变量设置(register globals)并移除他们 */
    function unregisterGlobals(){
       if (ini_get(&#39;register_globals&#39;)) {
           $array = array(&#39;_SESSION&#39;,&#39;_POST&#39;,&#39;_GET&#39;,&#39;_COOKIE&#39;,&#39;_REQUEST&#39;,&#39;_SERVER&#39;,&#39;_ENV&#39;,&#39;_FILES&#39;);
           foreach ($array as $value) {
               foreach ($GLOBALS[$value] as $key => $var) {
                  if ($var === $GLOBALS[$key]) {
                      unset($GLOBALS[$key]);
                  }
               }
           }
       }
    }
    /* 主请求方法,主要目的拆分URL请求 */
    function callHook() {
        global $url;
        $urlArray = array();
        $urlArray = explode("/",$url);
        $controller = $urlArray[0];
        array_shift($urlArray);
        $action = $urlArray[0];
        array_shift($urlArray);
        $queryString = $urlArray;
        $controllerName = $controller;
        $controller = ucwords($controller);
        $model = rtrim($controller, &#39;s&#39;);
        $controller .= &#39;Controller&#39;;
        $dispatch = new $controller($model,$controllerName,$action);
        if ((int)method_exists($controller, $action)) {
           call_user_func_array(array($dispatch,$action),$queryString);
        } else {
           /* 生成错误代码 */
        }
    }
    /* 自动加载控制器和模型 */
    function __autoload($className) {
        if (file_exists(ROOT . DS . &#39;library&#39; . DS . strtolower($className) . &#39;.class.php&#39;)) {
            require_once(ROOT . DS . &#39;library&#39; . DS . strtolower($className) . &#39;.class.php&#39;);
        } else if (file_exists(ROOT . DS . &#39;application&#39; . DS . &#39;controllers&#39; . DS . strtolower($className) . &#39;.php&#39;)) {
            require_once(ROOT . DS . &#39;application&#39; . DS . &#39;controllers&#39; . DS . strtolower($className) . &#39;.php&#39;);
        } else if (file_exists(ROOT . DS . &#39;application&#39; . DS . &#39;models&#39; . DS . strtolower($className) . &#39;.php&#39;)) {
            require_once(ROOT . DS . &#39;application&#39; . DS . &#39;models&#39; . DS . strtolower($className) . &#39;.php&#39;);
        } else {
           /* 生成错误代码 */
        }
    }
    setReporting();
    removeMagicQuotes();
    unregisterGlobals();
    callHook();
登入後複製

接下来的操作就是在library中建立程序所需要的基类,包括控制器、模型和视图的基类。

新建控制器基类为controller.class.php,控制器的主要功能就是总调度,具体具体内容如下:

<?php
    class Controller {
        protected $_model;
        protected $_controller;
        protected $_action;
        protected $_template;
        function __construct($model, $controller,$action) {
            $this->_controller = $controller;
            $this->_action = $action;
            $this->_model = $model;
            $this->$model =& new $model;
            $this->_template =& new Template($controller,$action);
        }
        function set($name,$value) {
            $this->_template->set($name,$value);
        }
        function __destruct() {
            $this->_template->render();
        }
    }
登入後複製

新建控制器基类为model.class.php,考虑到模型需要对数据库进行处理,所以可以新建一个数据库基类sqlquery.class.php,模型去继承sqlquery.class.php。

新建sqlquery.class.php,代码如下:

<?php
    class SQLQuery {
        protected $_dbHandle;
        protected $_result;
        /** 连接数据库 **/
        function connect($address, $account, $pwd, $name) {
            $this->_dbHandle = @mysql_connect($address, $account, $pwd);
            if ($this->_dbHandle != 0) {
               if (mysql_select_db($name, $this->_dbHandle)) {
                   return 1;
               }else {
                   return 0;
               }
            }else {
               return 0;
            }
         }
        /** 中断数据库连接 **/
        function disconnect() {
             if (@mysql_close($this->_dbHandle) != 0) {
                 return 1;
             } else {
                 return 0;
             }
        }
        /** 查询所有数据表内容 **/
        function selectAll() {
            $query = &#39;select * from `&#39;.$this->_table.&#39;`&#39;;
            return $this->query($query);
        }
        /** 查询数据表指定列内容 **/
        function select($id) {
            $query = &#39;select * from `&#39;.$this->_table.&#39;` where `id` = \&#39;&#39;.mysql_real_escape_string($id).&#39;\&#39;&#39;;
            return $this->query($query, 1);
        }
        /** 自定义SQL查询语句 **/
        function query($query, $singleResult = 0) {
            $this->_result = mysql_query($query, $this->_dbHandle);
            if (preg_match("/select/i",$query)) {
                 $result = array();
                 $table = array();
                 $field = array();
                 $tempResults = array();
                 $numOfFields = mysql_num_fields($this->_result);
                 for ($i = 0; $i < $numOfFields; ++$i) {
                      array_push($table,mysql_field_table($this->_result, $i));
                      array_push($field,mysql_field_name($this->_result, $i));
                  }
                 while ($row = mysql_fetch_row($this->_result)) {
                     for ($i = 0;$i < $numOfFields; ++$i) {
                        $table[$i] = trim(ucfirst($table[$i]),"s");
                        $tempResults[$table[$i]][$field[$i]] = $row[$i];
                     }
                     if ($singleResult == 1) {
                         mysql_free_result($this->_result);
                         return $tempResults;
                     }
                     array_push($result,$tempResults);
                 }
                 mysql_free_result($this->_result);
                 return($result);
             }
          }
         /** 返回结果集行数 **/
        function getNumRows() {
            return mysql_num_rows($this->_result);
        }
        /** 释放结果集内存 **/
        function freeResult() {
            mysql_free_result($this->_result);
        }
       /** 返回MySQL操作错误信息 **/
       function getError() {
           return mysql_error($this->_dbHandle);
       }
    }
登入後複製

新建model.class.php,代码如下:

<?php
    class Model extends SQLQuery{
        protected $_model;
        function __construct() {
            $this->connect(DB_HOST,DB_USER,DB_PASSWORD,DB_NAME);
            $this->_model = get_class($this);
            $this->_table = strtolower($this->_model)."s";
        }
        function __destruct() {
        }
    }
登入後複製

新建视图基类为template.class.php,具体代码如下:

<?php
    class Template {
       protected $variables = array();
       protected $_controller;
       protected $_action;
       function __construct($controller,$action) {
           $this->_controller = $controller;
           $this->_action =$action;
       }
       /* 设置变量 */
       function set($name,$value) {
            $this->variables[$name] = $value;
       }
       /* 显示模板 */
       function render() {
           extract($this->variables);
           if (file_exists(ROOT.DS. &#39;application&#39; .DS. &#39;views&#39; .DS. $this->_controller .DS. &#39;header.php&#39;)) {
               include(ROOT.DS. &#39;application&#39; .DS. &#39;views&#39; .DS. $this->_controller .DS. &#39;header.php&#39;);
           } else {
               include(ROOT.DS. &#39;application&#39; .DS. &#39;views&#39; .DS. &#39;header.php&#39;);
           }
           include (ROOT.DS. &#39;application&#39; .DS. &#39;views&#39; .DS. $this->_controller .DS. $this->_action . &#39;.php&#39;);
           if (file_exists(ROOT.DS. &#39;application&#39; .DS. &#39;views&#39; .DS. $this->_controller .DS. &#39;footer.php&#39;)) {
               include (ROOT.DS. &#39;application&#39; .DS. &#39;views&#39; .DS. $this->_controller .DS. &#39;footer.php&#39;);
           } else {
               include (ROOT.DS. &#39;application&#39; .DS. &#39;views&#39; .DS. &#39;footer.php&#39;);
           }
        }
    }
登入後複製

做完了以上这么多操作,基本上整个MVC框架已经出来了,下面就该制作我们的站点了。我们要做的站点其实很简单,一个ToDo程序。

首先是在我们的/application/controller/ 目录下面新建一个站点控制器类为ItemsController,命名为itemscontroller.php,内容为:

<?php
    class ItemsController extends Controller {
       function view($id = null,$name = null) {
           $this->set(&#39;title&#39;,$name.&#39; - My Todo List App&#39;);
           $this->set(&#39;todo&#39;,$this->Item->select($id));
       }
       function viewall() {
           $this->set(&#39;title&#39;,&#39;All Items - My Todo List App&#39;);
           $this->set(&#39;todo&#39;,$this->Item->selectAll());
       }
       function add() {
           $todo = $_POST[&#39;todo&#39;];
           $this->set(&#39;title&#39;,&#39;Success - My Todo List App&#39;);
           $this->set(&#39;todo&#39;,$this->Item->query(&#39;insert into items (item_name) values (\&#39;&#39;.mysql_real_escape_string($todo).&#39;\&#39;)&#39;));
       }
       function delete($id) {
           $this->set(&#39;title&#39;,&#39;Success - My Todo List App&#39;);
           $this->set(&#39;todo&#39;,$this->Item->query(&#39;delete from items where id = \&#39;&#39;.mysql_real_escape_string($id).&#39;\&#39;&#39;));
       }
    }
登入後複製

接下来就是先建站点的模型,在我们的/application/model/ 目录下面先建一个站点模型类为Item,内容直接继承Model,代码如下:

<?php
class Item extends Model {
}
登入後複製

最后一步是设置我们站点的视图部分,我们现在/application/views/目录下新建一个items的文件夹,再在items文件夹下建立与控制器重Action相同的文件,分别为view.php,viewall.php,add.php,delete.php,考虑到这么页面中可能需要共用页首和页尾,所以再新建两个文件,命名为header.php,footer.php,每个文件的代码如下:

view.php文件:查看单条待处理事务

<h2><?php echo $todo[&#39;Item&#39;][&#39;item_name&#39;]?></h2>
<a href="../../../items/delete/<?php echo $todo[&#39;Item&#39;][&#39;id&#39;]?>">
<span>Delete this item</span>
</a>
登入後複製

viewall.php文件:查看所有待处理事务

<form action="../items/add" method="post">
    <input type="text" value="I have to..." onclick="this.value=&#39;&#39;" name="todo"> <input type="submit" value="add">
</form>
<br/><br/>
<?php $number = 0?>
<?php foreach ($todo as $todoitem):?>
    <a href="../items/view/<?php echo $todoitem[&#39;Item&#39;][&#39;id&#39;]?>/<?php echo strtolower(str_replace(" ","-",$todoitem[&#39;Item&#39;][&#39;item_name&#39;]))?>">
        <span>
            <?php echo ++$number?>
            <?php echo $todoitem[&#39;Item&#39;][&#39;item_name&#39;]?>
        </span>
    </a><br/>
<?php endforeach?>
登入後複製

add.php文件:添加待处理事务

<a href="../items/viewall">Todo successfully added. Click here to go back.</a><br/>
登入後複製

delete.php文件:删除事务

<a href="../../items/viewall">Todo successfully deleted. Click here to go back.</a><br/>
登入後複製

header.php:页首文件

<html>
<head>
<title><?php echo $title?></title>
<style>
.item {width:400px;}
input {color:#222222;font-family:georgia,times;font-size:24px;font-weight:normal;line-height:1.2em;color:black;}
a {color:#222222;font-family:georgia,times;font-size:24px;font-weight:normal;line-height:1.2em;color:black;text-decoration:none;}
a:hover {background-color:#BCFC3D;}
h1 {color:#000000;font-size:41px;letter-spacing:-2px;line-height:1em;font-family:helvetica,arial,sans-serif;border-bottom:1px dotted #cccccc;}
h2 {color:#000000;font-size:34px;letter-spacing:-2px;line-height:1em;font-family:helvetica,arial,sans-serif;}
</style>
</head>
<body>
<h1 id="My-nbsp-Todo-List-nbsp-App">My Todo-List App</h1>
登入後複製

footer.php:页尾文件

</body>
</html>
登入後複製

当然还有一个必不可少的操作就是在数据中中建立一张表,具体代码如下:

CREATE TABLE IF NOT EXISTS `items` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `item_name` varchar(255) NOT NULL,
    PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=17 ;
登入後複製

至此一个使用MVC开发的网站就开发完成了,你现在可以通过访问http://localhost/todo/items/viewall 查看新建的站点。


本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

適用於 Ubuntu 和 Debian 的 PHP 8.4 安裝和升級指南 適用於 Ubuntu 和 Debian 的 PHP 8.4 安裝和升級指南 Dec 24, 2024 pm 04:42 PM

PHP 8.4 帶來了多項新功能、安全性改進和效能改進,同時棄用和刪除了大量功能。 本指南介紹如何在 Ubuntu、Debian 或其衍生版本上安裝 PHP 8.4 或升級到 PHP 8.4

如何設定 Visual Studio Code (VS Code) 進行 PHP 開發 如何設定 Visual Studio Code (VS Code) 進行 PHP 開發 Dec 20, 2024 am 11:31 AM

Visual Studio Code,也稱為 VS Code,是一個免費的原始碼編輯器 - 或整合開發環境 (IDE) - 可用於所有主要作業系統。 VS Code 擁有大量針對多種程式語言的擴展,可以輕鬆編寫

在PHP API中說明JSON Web令牌(JWT)及其用例。 在PHP API中說明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

php程序在字符串中計數元音 php程序在字符串中計數元音 Feb 07, 2025 pm 12:12 PM

字符串是由字符組成的序列,包括字母、數字和符號。本教程將學習如何使用不同的方法在PHP中計算給定字符串中元音的數量。英語中的元音是a、e、i、o、u,它們可以是大寫或小寫。 什麼是元音? 元音是代表特定語音的字母字符。英語中共有五個元音,包括大寫和小寫: a, e, i, o, u 示例 1 輸入:字符串 = "Tutorialspoint" 輸出:6 解釋 字符串 "Tutorialspoint" 中的元音是 u、o、i、a、o、i。總共有 6 個元

您如何在PHP中解析和處理HTML/XML? 您如何在PHP中解析和處理HTML/XML? Feb 07, 2025 am 11:57 AM

本教程演示瞭如何使用PHP有效地處理XML文檔。 XML(可擴展的標記語言)是一種用於人類可讀性和機器解析的多功能文本標記語言。它通常用於數據存儲

解釋PHP中的晚期靜態綁定(靜態::)。 解釋PHP中的晚期靜態綁定(靜態::)。 Apr 03, 2025 am 12:04 AM

靜態綁定(static::)在PHP中實現晚期靜態綁定(LSB),允許在靜態上下文中引用調用類而非定義類。 1)解析過程在運行時進行,2)在繼承關係中向上查找調用類,3)可能帶來性能開銷。

什麼是PHP魔術方法(__ -construct,__destruct,__call,__get,__ set等)並提供用例? 什麼是PHP魔術方法(__ -construct,__destruct,__call,__get,__ set等)並提供用例? Apr 03, 2025 am 12:03 AM

PHP的魔法方法有哪些? PHP的魔法方法包括:1.\_\_construct,用於初始化對象;2.\_\_destruct,用於清理資源;3.\_\_call,處理不存在的方法調用;4.\_\_get,實現動態屬性訪問;5.\_\_set,實現動態屬性設置。這些方法在特定情況下自動調用,提升代碼的靈活性和效率。

PHP和Python:比較兩種流行的編程語言 PHP和Python:比較兩種流行的編程語言 Apr 14, 2025 am 12:13 AM

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

See all articles