『壹』 php類的實例化問題
只要是實例化一個類,不論是不是在同一個文件夾下,只要不是在當前腳本聲明的,都是需要include的. 加入一個對象實例化一個不存在的類,這時候機會調用類的一個魔術方法__autoload方法,參數是你要實例化的這個類名,如果你將這個autoload聲明成了一個方法,方法裡面定義如何查找你需要的這個類,在哪裡查找,並且找到了就自動引入,那就不需要你時時刻刻都來引入類文件了
『貳』 PHP能在類中實例化一個類嗎
重復定義類了,修改一個類名為Mysql ,改為其它名就可以了
『叄』 使用PHP寫一個類和一個控制器
<?php
/**
*以下代碼用於資料庫操作類的封裝
*
* @author rex<[email protected]>
* @version 1.0
* @since 2015
*/
class Mysql{
//資料庫連接返回值
private $conn;
/**
* [構造函數,返回值給$conn]
* @param [string] $hostname [主機名]
* @param [string] $username[用戶名]
* @param [string] $password[密碼]
* @param [string] $dbname[資料庫名]
* @param [string] $charset[字元集]
* @return [null]
*/
function __construct($hostname,$username,$password,$dbname,$charset='utf8'){
$conn = @mysql_connect($hostname,$username,$password);
if(!$conn){
echo '連接失敗,請聯系管理員';
exit;
}
$this->conn = $conn;
$res = mysql_select_db($dbname);
if(!$res){
echo '連接失敗,請聯系管理員';
exit;
}
mysql_set_charset($charset);
}
function __destruct(){
mysql_close();
}
/**
* [getAll 獲取所有信息]
* @param [string] $sql [sql語句]
* @return [array] [返回二維數組]
*/
function getAll($sql){
$result = mysql_query($sql,$this->conn);
$data = array();
if($result && mysql_num_rows($result)>0){
while($row = mysql_fetch_assoc($result)){
$data[] = $row;
}
}
return $data;
}
/**
* [getOne 獲取單條數據]
* @param [string] $sql [sql語句]
* @return [array] [返回一維數組]
*/
function getOne($sql){
$result = mysql_query($sql,$this->conn);
$data = array();
if($result && mysql_num_rows($result)>0){
$data = mysql_fetch_assoc($result);
}
return $data;
}
/**
* [getOne 獲取單條數據]
* @param [string] $table [表名]
* @param [string] $data [由欄位名當鍵,屬性當鍵值的一維數組]
* @return [type] [返回false或者插入數據的id]
*/
function insert($table,$data){
$str = '';
$str .="INSERT INTO `$table` ";
$str .="(`".implode("`,`",array_keys($data))."`) ";
$str .=" VALUES ";
$str .= "('".implode("','",$data)."')";
$res = mysql_query($str,$this->conn);
if($res && mysql_affected_rows()>0){
return mysql_insert_id();
}else{
return false;
}
}
/**
* [update 更新資料庫]
* @param [string] $table [表名]
* @param [array] $data [更新的數據,由欄位名當鍵,屬性當鍵值的一維數組]
* @param [string] $where [條件,『欄位名』=『欄位屬性』]
* @return [type] [更新成功返回影響的行數,更新失敗返回false]
*/
function update($table,$data,$where){
$sql = 'UPDATE '.$table.' SET ';
foreach($data as $key => $value){
$sql .= "`{$key}`='{$value}',";
}
$sql = rtrim($sql,',');
$sql .= " WHERE $where";
$res = mysql_query($sql,$this->conn);
if($res && mysql_affected_rows()){
return mysql_affected_rows();
}else{
return false;
}
}
/**
* [delete 刪除數據]
* @param [string] $table [表名]
* @param [string] $where [條件,『欄位名』=『欄位屬性』]
* @return [type] [成功返回影響的行數,失敗返回false]
*/
function del($table,$where){
$sql = "DELETE FROM `{$table}` WHERE {$where}";
$res = mysql_query($sql,$this->conn);
if($res && mysql_affected_rows()){
return mysql_affected_rows();
}else{
return false;
}
}
}
實例化類:
<?php
//包含資料庫操作類文件
include 'mysql.class.php';
//設置傳入參數
$hostname='localhost';
$username='root';
$password='123456';
$dbname='aisi';
$charset = 'utf8';
//實例化對象
$db = new Mysql($hostname,$username,$password,$dbname);
//獲取一條數據
$sql = "SELECT count(as_article_id) as count FROM as_article where as_article_type_id=1";
$count = $db->getOne($sql);
//獲取多條數據
$sql = "SELECT * FROM as_article where as_article_type_id=1 order by as_article_addtime desc limit $start,$limit";
$service = $db->getAll($sql);
//插入數據
$arr = array(
'as_article_title'=>'資料庫操作類',
'as_article_author'=>'rex',
);
$res = $db->insert('as_article',$arr);
//更新數據
$arr = array(
'as_article_title'=>'實例化對象',
'as_article_author'=>'Lee',
);
$where = "as_article_id=1";
$res = $db->update('as_article',$arr,$where);
//刪除數據
$where = "as_article_id=1";
$res = $db->del('as_article',$where);
?>
getOne方法傳入$sql的sql語句用於查詢單條數據並返回一維數組;getAll方法同樣傳入sql語句,用於查詢多條數據,並返回二維數組;insert方法傳入表名和關聯數組,返回boolen型或者插入數據對應索引;update方法傳入表名、關聯數組和條件,返回boolen或者影響的行數;del方法傳入表名和條件,返回boolen型。
『肆』 php實例化一個類,需要小括弧()嗎
是不是定義了function __autoload?如果是的話,在你new一個本腳本不存在的類時,會自動調用該方法在指定的目錄進行指定引入(include);如果是tp框架,那就是這個類被定義到了一個function.php中,自動完成引入.
『伍』 如何在PHP中定義一個類
當你聲明一個類,你需要列出對象應有的所有變數和所有函數?被稱為屬性和方法圖1中顯示了一個類的構成. 注意在大括弧({})內你只能聲明變數或者函數. 圖2中顯示了如何在一個類中定義三個屬性和兩個方法.
以下為引用的內容:
class Name extends Another Class
{
Access Variable Declaration
Access Function Declaration
}
name = $name;
$this->password = $password;
$this->lastLogin = time();
$this->accesses++;
}
// 獲取最後訪問的時間
function getLastLogin()
{
return(date("M d Y", $this->lastLogin));
}
}
//創建一個對象的實例
$user = new User("Leon", "sdf123");
//獲取最後訪問的時間
print($user->getLastLogin() ."\n");
//列印用戶名
print("$user->name\n");
?>
當你聲明屬性,你不需要指明數據類型. 變數可能是整型,字元串或者是另一個對象,這取決於實際情況.在聲明屬性時增加註釋是一個好主意,標記上屬性的含義和數據類型.
當你聲明一個方法,你所做的和在類外部定義一個函數是一樣的. 方法和屬性都有各自的命名空間. 這意味著你可以安全地建立一個與類外部函數同名的方法,兩者不會沖突. 例如,一個類中可以定義一個名為date()的方法. 但是你不能將一個方法命名為PHP的關鍵字,如for或者while.
類方法可能包含PHP中所謂的type hint. Type hint 是另一個傳遞參數給方法的類的名字. 如果你的腳本調用方法並傳遞一個不是類的實例的變數,PHP將產生一個」致命(fatal)錯誤」 . 你可能沒有給其它類型給出type hint,就像整型,字元串,或者布爾值. 在書寫的時候, type hint是否應當包含數組類型仍存在爭議.
Type hint是測試函數參數或者運算符的實例的數據類型的捷徑. 你可能總是返回這個方法. 確認你強制讓一個參數必須是哪種數據類型,如整型. 圖3 確保編譯類只產生Widget的實例
以下為引用的內容:
<?php
//組件
class Widget
{
public $name='none';
public $created=FALSE;
}
//裝配器
class Assembler
{
public function make(Widget $w)
{
print("Making $w->name\n");
$w->created=TRUE;
}
}
//建立一個組件對象
$thing = new Widget;
$thing->name = 'Gadget';
//裝配組件
Assembler::make($thing);
?>
除了傳遞參數的變數外,方法含有一個特殊的變數. 它代表類的個別實例. 你應當用這個來指向對象的屬性和其它方法.一些面向對象的語言假設一個不合格的變數提交給本地屬性,但在PHP中方法的任何變數只是在方法的一定范圍內. 注意在User類的構造函數中這個變數的使用圖2.
『陸』 php怎麼實例化有依賴注入的類
PHP依賴注入的理解。分享給大家供大家參考,具體如下:
看Laravel的IoC容器文檔只是介紹實例,但是沒有說原理,之前用MVC框架都沒有在意這個概念,無意中在phalcon的文檔中看到這個詳細的介紹,感覺豁然開朗,復制粘貼過來,主要是好久沒有寫東西了,現在確實很懶變得!
首先,我們假設,我們要開發一個組件命名為SomeComponent。這個組件中現在將要注入一個資料庫連接。
在這個例子中,資料庫連接在component中被創建,這種方法是不切實際的,這樣做的話,我們將不能改變資料庫連接參數及資料庫類型等一些參數。
class SomeComponent {
/**
* The instantiation of the connection is hardcoded inside
* the component so is difficult to replace it externally
* or change its behavior
*/
public function someDbTask()
{
$connection = new Connection(array(
"host" => "localhost",
"username" => "root",
"password" => "secret",
"dbname" => "invo"
));
// ...
}
}
$some = new SomeComponent();
$some->someDbTask();
為了解決上面所說的問題,我們需要在使用前創建一個外部連接,並注入到容器中。就目前而言,這看起來是一個很好的解決方案:
class SomeComponent {
protected $_connection;
/**
* Sets the connection externally
*/
public function setConnection($connection)
{
$this->_connection = $connection;
}
public function someDbTask()
{
$connection = $this->_connection;
// ...
}
}
$some = new SomeComponent();
//Create the connection
$connection = new Connection(array(
"host" => "localhost",
"username" => "root",
"password" => "secret",
"dbname" => "invo"
));
//Inject the connection in the component
$some->setConnection($connection);
$some->someDbTask();
現在我們來考慮一個問題,我們在應用程序中的不同地方使用此組件,將多次創建資料庫連接。使用一種類似全局注冊表的方式,從這獲得一個資料庫連接實例,而不是使用一次就創建一次。
class Registry
{
/**
* Returns the connection
*/
public static function getConnection()
{
return new Connection(array(
"host" => "localhost",
"username" => "root",
"password" => "secret",
"dbname" => "invo"
));
}
}
class SomeComponent
{
protected $_connection;
/**
* Sets the connection externally
*/
public function setConnection($connection){
$this->_connection = $connection;
}
public function someDbTask()
{
$connection = $this->_connection;
// ...
}
}
$some = new SomeComponent();
//Pass the connection defined in the registry
$some->setConnection(Registry::getConnection());
$some->someDbTask();
現在,讓我們來想像一下,我們必須在組件中實現兩個方法,首先需要創建一個新的資料庫連接,第二個總是獲得一個共享連接:
class Registry
{
protected static $_connection;
/**
* Creates a connection
*/
protected static function _createConnection()
{
return new Connection(array(
"host" => "localhost",
"username" => "root",
"password" => "secret",
"dbname" => "invo"
));
}
/**
* Creates a connection only once and returns it
*/
public static function getSharedConnection()
{
if (self::$_connection===null){
$connection = self::_createConnection();
self::$_connection = $connection;
}
return self::$_connection;
}
/**
* Always returns a new connection
*/
public static function getNewConnection()
{
return self::_createConnection();
}
}
class SomeComponent
{
protected $_connection;
/**
* Sets the connection externally
*/
public function setConnection($connection){
$this->_connection = $connection;
}
/**
* This method always needs the shared connection
*/
public function someDbTask()
{
$connection = $this->_connection;
// ...
}
/**
* This method always needs a new connection
*/
public function someOtherDbTask($connection)
{
}
}
$some = new SomeComponent();
//This injects the shared connection
$some->setConnection(Registry::getSharedConnection());
$some->someDbTask();
//Here, we always pass a new connection as parameter
$some->someOtherDbTask(Registry::getConnection());
到此為止,我們已經看到了如何使用依賴注入解決我們的問題。不是在代碼內部創建依賴關系,而是讓其作為一個參數傳遞,這使得我們的程序更容易維護,降低程序代碼的耦合度,實現一種松耦合。但是從長遠來看,這種形式的依賴注入也有一些缺點。
例如,如果組件中有較多的依賴關系,我們需要創建多個setter方法傳遞,或創建構造函數進行傳遞。另外,每次使用組件時,都需要創建依賴組件,使代碼維護不太易,我們編寫的代碼可能像這樣:
//Create the dependencies or retrieve them from the registry
$connection = new Connection();
$session = new Session();
$fileSystem = new FileSystem();
$filter = new Filter();
$selector = new Selector();
//Pass them as constructor parameters
$some = new SomeComponent($connection, $session, $fileSystem, $filter, $selector);
// ... or using setters
$some->setConnection($connection);
$some->setSession($session);
$some->setFileSystem($fileSystem);
$some->setFilter($filter);
$some->setSelector($selector);
我想,我們不得不在應用程序的許多地方創建這個對象。如果你不需要依賴的組件後,我們又要去代碼注入部分移除構造函數中的參數或者是setter方法。為了解決這個問題,我們再次返回去使用一個全局注冊表來創建組件。但是,在創建對象之前,它增加了一個新的抽象層:
class SomeComponent
{
// ...
/**
* Define a factory method to create SomeComponent instances injecting its dependencies
*/
public static function factory()
{
$connection = new Connection();
$session = new Session();
$fileSystem = new FileSystem();
$filter = new Filter();
$selector = new Selector();
return new self($connection, $session, $fileSystem, $filter, $selector);
}
}
這一刻,我們好像回到了問題的開始,我們正在創建組件內部的依賴,我們每次都在修改以及找尋一種解決問題的辦法,但這都不是很好的做法。
一種實用和優雅的來解決這些問題,是使用容器的依賴注入,像我們在前面看到的,容器作為全局注冊表,使用容器的依賴注入做為一種橋梁來解決依賴可以使我們的代碼耦合度更低,很好的降低了組件的復雜性:
class SomeComponent
{
protected $_di;
public function __construct($di)
{
$this->_di = $di;
}
public function someDbTask()
{
// Get the connection service
// Always returns a new connection
$connection = $this->_di->get('db');
}
public function someOtherDbTask()
{
// Get a shared connection service,
// this will return the same connection everytime
$connection = $this->_di->getShared('db');
//This method also requires a input filtering service
$filter = $this->_db->get('filter');
}
}
$di = new Phalcon\DI();
//Register a "db" service in the container
$di->set('db', function(){
return new Connection(array(
"host" => "localhost",
"username" => "root",
"password" => "secret",
"dbname" => "invo"
));
});
//Register a "filter" service in the container
$di->set('filter', function(){
return new Filter();
});
//Register a "session" service in the container
$di->set('session', function(){
return new Session();
});
//Pass the service container as unique parameter
$some = new SomeComponent($di);
$some->someTask();
現在,該組件只有訪問某種service的時候才需要它,如果它不需要,它甚至不初始化,以節約資源。該組件是高度解耦。他們的行為,或者說他們的任何其他方面都不會影響到組件本身。我們的實現辦法
Phalcon\DI 是一個實現了服務的依賴注入功能的組件,它本身也是一個容器。
由於Phalcon高度解耦,Phalcon\DI 是框架用來集成其他組件的必不可少的部分,開發人員也可以使用這個組件依賴注入和管理應用程序中不同類文件的實例。
基本上,這個組件實現了 Inversion of Control 模式。基於此,對象不再以構造函數接收參數或者使用setter的方式來實現注入,而是直接請求服務的依賴注入。這就大大降低了整體程序的復雜性,因為只有一個方法用以獲得所需要的一個組件的依賴關系。
此外,這種模式增強了代碼的可測試性,從而使它不容易出錯。
在容器中注冊服務
框架本身或開發人員都可以注冊服務。當一個組件A要求調用組件B(或它的類的一個實例),可以從容器中請求調用組件B,而不是創建組件B的一個實例。
這種工作方式為我們提供了許多優點:
我們可以更換一個組件,從他們本身或者第三方輕松創建。
在組件發布之前,我們可以充分的控制對象的初始化,並對對象進行各種設置。
我們可以使用統一的方式從組件得到一個結構化的全局實例
服務可以通過以下幾種方式注入到容器:
//Create the Dependency Injector Container
$di = new Phalcon\DI();
//By its class name
$di->set("request", 'Phalcon\Http\Request');
//Using an anonymous function, the instance will lazy loaded
$di->set("request", function(){
return new Phalcon\Http\Request();
});
//Registering directly an instance
$di->set("request", new Phalcon\Http\Request());
//Using an array definition
$di->set("request", array(
"className" => 'Phalcon\Http\Request'
));
在上面的例子中,當向框架請求訪問一個請求數據時,它將首先確定容器中是否存在這個」reqeust」名稱的服務。
容器會反回一個請求數據的實例,開發人員最終得到他們想要的組件。
在上面示例中的每一種方法都有優缺點,具體使用哪一種,由開發過程中的特定場景來決定的。
用一個字元串來設定一個服務非常簡單,但缺少靈活性。設置服務時,使用數組則提供了更多的靈活性,而且可以使用較復雜的代碼。lambda函數是兩者之間一個很好的平衡,但也可能導致更多的維護管理成本。
Phalcon\DI 提供服務的延遲載入。除非開發人員在注入服務的時候直接實例化一個對象,然後存存儲到容器中。在容器中,通過數組,字元串等方式存儲的服務都將被延遲載入,即只有在請求對象的時候才被初始化。
//Register a service "db" with a class name and its parameters
$di->set("db", array(
"className" => "Phalcon\Db\Adapter\Pdo\Mysql",
"parameters" => array(
"parameter" => array(
"host" => "localhost",
"username" => "root",
"password" => "secret",
"dbname" => "blog"
)
)
));
//Using an anonymous function
$di->set("db", function(){
return new Phalcon\Db\Adapter\Pdo\Mysql(array(
"host" => "localhost",
"username" => "root",
"password" => "secret",
"dbname" => "blog"
));
});
以上這兩種服務的注冊方式產生相同的結果。然後,通過數組定義的,在後面需要的時候,你可以修改服務參數:
$di->setParameter("db", 0, array(
"host" => "localhost",
"username" => "root",
"password" => "secret"
));
從容器中獲得服務的最簡單方式就是使用」get」方法,它將從容器中返回一個新的實例:
$request = $di->get("request");
或者通過下面這種魔術方法的形式調用:
$request = $di->getRequest();
Phalcon\DI 同時允許服務重用,為了得到一個已經實例化過的服務,可以使用 getShared() 方法的形式來獲得服務。
具體的 Phalcon\Http\Request 請求示例:
$request = $di->getShared("request");
參數還可以在請求的時候通過將一個數組參數傳遞給構造函數的方式:
$component = $di->get("MyComponent", array("some-parameter", "other"));
『柒』 php實例化類
<?php
class B{
function showme(){
return "i am B class function";
}
}
class A extends B{
function myshow(){
return B::showme()."--- this add by A function";
}
}
$test=new A();
echo $test->myshow();
?>
1、繼承關鍵字 :extends
PHP類的繼承,我們可以理解成共享被繼承類的內容。PHP中使用extends單一繼承的方法,請切忌!(非C++多繼承)被繼承的類我們叫做父類(基類)繼承者成為子類(派生類)。
2、PHP繼承的規則
CLASS1------>CLASS2------>CLASS3
依次被繼承,class3擁有class1、class2所以功能和屬性,避免方法和屬性重名。
『捌』 php實例化一個類,並分別訪問其public,private,protected屬性,查看有什麼不同
classTest{
public$var1;
public$var2;
publicfunction__construct(){
//構造函數
}
privatefunctionmypriAction(){
//私有方法,只能在類裡面訪問
}
(){
//私有方法,只能在類裡面和了類裡面訪問
}
publicfunctionpre($obj){
//公共方法,實例化以後可以調
echo"<pre>";
print_r($obj);
echo"</pre>";
}
}
$test=newTest();
$arr=array(1,2,3,4,5);
$test->pre($arr);