测试
namespace 会自动加载,但是我测试的两个文件并没有自动加载:
<code>#/DB/MySql.class.php namespace DB; class MySql { public function __construct() { var_dump(__FILE__); } } </code>
<code>#/index.php namespace Home; use DB\MySql; $mysql = new MySql(); </code>
报错
<code>Fatal error: Class 'DB\MySql' not found in D:\localhost\demo\space\index.php on line 23 </code>
修改
修改 index.php 改成如下,可以了,但是为什么不能自动加载?
<code>php</code><code>namespace Home; use DB\MySql; spl_autoload_register(function ($class) { if ($class) { $file = str_replace('\\', '/', $class); $file .= '.class.php'; if (file_exists($file)) { include $file; } } }); $mysql = new MySql(); </code>
回复内容:
测试
namespace 会自动加载,但是我测试的两个文件并没有自动加载:
<code>#/DB/MySql.class.php namespace DB; class MySql { public function __construct() { var_dump(__FILE__); } } </code>
<code>#/index.php namespace Home; use DB\MySql; $mysql = new MySql(); </code>
报错
<code>Fatal error: Class 'DB\MySql' not found in D:\localhost\demo\space\index.php on line 23 </code>
修改
修改 index.php 改成如下,可以了,但是为什么不能自动加载?
<code>php</code><code>namespace Home; use DB\MySql; spl_autoload_register(function ($class) { if ($class) { $file = str_replace('\\', '/', $class); $file .= '.class.php'; if (file_exists($file)) { include $file; } } }); $mysql = new MySql(); </code>
用Composer吧!
理由聽我娓娓道來!
PHP最早讀取套件的方法
初學PHP時,最早會面對的問題之一就是require與include差別何在?
require_once與include_once又是什麼?
弄懂這些問題之後,如果不使用framework,直接開發,便常出現類似這樣的code:
<code>// whatever.php // 這檔案需要用到幾個類別 require 'xxx_class.php'; require 'yyy_class.php'; require 'zzz_class.php'; // ... </code>
然後在其他檔案會出現:
<code>// another.php // 這檔案需要用到幾個類別 require 'yyy_class.php'; require 'zzz_class.php'; // ... </code>
這樣的結果,會產生至少兩個問題:
1. 許多檔案用到同樣幾個class,於是在不同地方都需要載入一次。
2. 當類別多了起來,會顯得很亂、忘記載入時還會出現error。
那麼,不如試試一種懶惰的作法?
寫一個php,負責載入所有類別:
<code>// load_everything.php require 'xxx_class.php'; require 'yyy_class.php'; require 'zzz_class.php'; require 'aaa_class.php'; require 'bbb_class.php'; require 'ccc_class.php'; </code>
然後在其他檔案都載入這支檔案即可:
<code>require 'load_everything.php' </code>
結果新問題又來了:當類別很多的時候,隨便一個web page都會載入一堆code,吃爆記憶體,怎麼辦呢?
__autoload
為了解決這個問題,PHP 5開始提供__autoload這種俗稱「magic method」的函式。
當你要使用的類別PHP找不到時,它會將類別名稱當成字串丟進這個函式,在PHP噴error投降之前,做最後的嘗試:
<code>// autoload.php function __autoload($classname) { if ($classname === 'xxx.php'){ $filename = "./". $classname .".php"; include_once($filename); } else if ($classname === 'yyy.php'){ $filename = "./other_library/". $classname .".php"; include_once($filename); } else if ($classname === 'zzz.php'){ $filename = "./my_library/". $classname .".php"; include_once($filename); } // blah } </code>
也因為PHP這種「投降前最後一次嘗試」的行為,有時會讓沒注意到的人困惑「奇怪我的code怎麼跑得動?我根本沒有require啊..」,所以被稱為「magic method」。
如此一來,問題似乎解決了?
可惜還是有小缺點..,就是這個__autoload函式內容會變得很巨大。以上面的例子來說,一下會去根目錄找、一下會去other_library資料夾、一下會去my_library資料夾尋找。在整理檔案的時候,顯得有些混亂。
spl_autoload_register
於是PHP從5.1.2開始,多提供了一個函式。
可以多寫幾個autoload函式,然後註冊起來,效果跟直接使用__autoload相同。
現在可以針對不同用途的類別,分批autoload了。
<code>spl_autoload_register('my_library_loader'); spl_autoload_register('other_library_loader'); spl_autoload_register('basic_loader'); function my_library_loader($classname) { $filename = "./my_library/". $classname .".php"; include_once($filename); } function other_library_loader($classname) { $filename = "./other_library/". $classname .".php"; include_once($filename); } function basic_loader($classname) { $filename = "./". $classname .".php"; include_once($filename); } </code>
每個loader內容可以做很多變化。可以多寫判斷式讓它更智慧、可以進行字串處理…。
自動載入類別的問題終於解決了…。
但是光上面的code也有15行,而且在每個project一定都會寫類似的東西。有沒有辦法自動產生這15行呢?
我的願望很簡單,我告訴你,反正我有my_library資料夾跟other_library資料夾,你自己進去看到什麼類別就全部載入好不好…?
阿不對,全部載入剛又說效能不好,那你進去看到什麼就全部想辦法用spl_autoload_register記起來好不好…?
我懶得打15行了,我只想打這幾個字:
$please_autoload = array( 'my_library', 'other_library');
可不可以發明一個工具,去吃$please_autoload這個變數,然後自己想辦法載入一切啊…?
ㄟ等等,我連php程式碼都懶得打了,在web領域JSON格式更簡潔。允許我這樣打,好嗎?
<code>{ "autoload": [ "my_library", "other_library" ] } </code>
然後誰來個工具幫我產生一大串autoload相關的php程式碼吧…,可以嗎?
可以。
Composer登場
首先,裝好composer(本文不介紹如何安裝。)
再來,建立一個composer.json檔,裡面輸入這些:
<code>{ "autoload": { "classmap": [ "my_library", "other_library" ] } } </code>
比原本希望的多打了一些字,不過差不多。
再來,在terminal輸入
composer install
執行成功之後,你會看到一個vendor資料夾,內含一個autoload.php。
沒錯,跟你夢想的一樣。你只要載入這個檔案:
require 'vendor/autoload.php';
你需要的所有類別,都會在適當的時候、以適當的方式自動載入。
php再也不會噴error說你「類別尚未定義」了!
這vendor資料夾裡面的一切,都只是php code而已,並沒有特別神奇的地方。只要去看autoload.php的原始碼,就能知道composer到底寫了哪些php code給你。
ㄟ等等,我寫的類別都放在my_library裡面了,other_library都是網路上copy下來的現成類別。我想要用Google API的Client類別、Doctrine資料庫管理抽象層類別、還有guzzlehttp的發送request類別。
我連去下載這些檔案、然後丟進這個資料夾都懶得做了,我根本不想手動建立other_library這個資料夾。composer真那麼神…不如連下載都幫我自動下載?可以嗎?
可以。
查詢一下那幾個套件在「https://packagist.org/」的名稱、還有你需要的版本號。
把剛剛的composer.json改成這樣:
<code>{ "require": { "google/apiclient": "1.0.*@beta", "guzzlehttp/guzzle": "~4.0", "doctrine/dbal": "~2.4" }, "autoload": { "classmap": [ "my_library" ] } } </code>
然後’composer install’指令除了自動載入你的類別之外、還會自動下載你需要的類別、然後自動載入它們。
一樣require ‘vendor/autoload.php’就可以了。composer實在是太棒了
我的部落格
http://blog.turn.tw/?p=1039
http://blog.turn.tw/?p=1122
命名空间跟文件加载并无直接关系,
只是有些语言,将命名空间结构和文件结构对应起来了。
以php为例,
一般的命名空间结构,跟php文件结构是存在映射关系的,通过命名空间名称,就能算出该类的实际存储位置,
然后实例化的时候,会触发用设置的spl自动加载函数将文件引入。
传送门
https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md
希望能有帮助
<code>namespace Home; use DB\MySql; $mysql = new MySql(); </code>
实际执行代码的时候是 new \DB\MySql();
找不到这个文件的时候就会调用你的autoload函数 并file_exists("DB/MySql.class.php")
,在当前目录下查找这个文件,在找不到的情况下然后就是你看到的 错误

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

在php中,可以使用substr()函数来读取字符串后几个字符,只需要将该函数的第二个参数设置为负值,第三个参数省略即可;语法为“substr(字符串,-n)”,表示读取从字符串结尾处向前数第n个字符开始,直到字符串结尾的全部字符。

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

方法:1、用“str_replace(" ","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\ \;||\xc2\xa0)/","其他字符",$str)”语句。

查找方法:1、用strpos(),语法“strpos("字符串值","查找子串")+1”;2、用stripos(),语法“strpos("字符串值","查找子串")+1”。因为字符串是从0开始计数的,因此两个函数获取的位置需要进行加1处理。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

WebStorm Mac版
好用的JavaScript开发工具

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

Dreamweaver CS6
视觉化网页开发工具

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。