⑴ php pdo單例模式怎麼同時連接兩個資料庫
PHP pdo單例模式連接資料庫
';
if ( self::$pdo == null )
{
$host = '115.29.223.160';
$user = 'zhangwei';
$pwd = 'zhang111';
$dbname = 'wangzhan';
$dsn = "mysql:host=$host;dbname=$dbname;port=3306";
$pdo = new PDO ( $dsn, $user, $pwd );
$pdo->query('set names utf8;');
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
self::$pdo = $pdo;
}
return self::$pdo;
}
public static function getStmt ( $sql )
{
$pdo = self::getPdo ();
return $pdo -> prepare( $sql );
}
}
$sql = "INSERT INTO testss (wef,wef1) VALUES(?,?)";
$stmt = Db::getStmt ( $sql );
$stmt = Db::getStmt ( $sql );
?>
輸出結果
NULL
object(PDO)#1 (0) { }
第一次null 第二次再獲取就已經有了 不用重新連接了
單利模式好處就是保存變數 他是用static保存的 所以 退出函數 變數不會釋放
關於這個問題,差不多就是這個樣子的了,你如果不明白,可以自己去後盾瞅瞅,我這些都是在後盾上學的,有空可以去看一下,就算不喜歡也沒關系啊,何樂而不為呢?
⑵ 單例模式 資料庫 php 怎麼用
搭建好php開發環境,這個就不多講了,能找單例模式的應該有一定的php基礎
2
新建一個database.php文件存放資料庫信息
<?php
$db = array(
'host'=>'localhost',//地址
'user'=>'root',//資料庫用戶名
'password'=>'root',//資料庫密碼
'database'=>'ceshi',//資料庫名
)
?>
3
新建Mysql.class.php編寫資料庫連接類操作類添加需要的屬性和構造方法
構造函數載入資料庫配置文件連接資料庫
<?php
class db {
public $conn;
public static $sql;
public static $instance=null;
private function __construct(){
require_once('database.php');
$this->conn = mysqli_connect($db['host'],$db['user'],$db['password']);
if(!mysqli_select_db($this->conn,$db['database'])){
echo "失敗";
};
mysqli_query($this->conn,'set names utf8');
}
}
?>這樣試試吧如果你對php這類有興趣的話,可以和我一樣在後盾人經常看看教材,自己多看幾遍,慢慢的以後就明白了,希望能幫到你,給個採納吧謝謝
⑶ 什麼是PHP單例模式
PHP單例模式,就是一個對象只被生成一次,但該對象可以被其它眾多對象使用。單例模式使用最多的場景,是資料庫連接操作。我們知道,生成一個對象的操作是用new函數來實現,但是new對象都會消耗內存,而且有時候對同一個對象,在不同文件中可能會生成多次,這就造成了系統資源的浪費。然而使用單例模式,則可以很好的避免這種情況。
以資料庫為例,假設我們有一個資料庫的類,要實現資料庫連接。如果不使用單例模式,那麼在很多PHP文件中,我們可能到要創建這樣的一個連接,這其實是對資源的很大浪費。那麼下面介紹單例模式實現方法:
classDatabase
{
//定義一個屬性,該屬性是靜態的保護或私有屬性
protectedstatic$db;
//這里構造函數一定要是私有方法
privatefunction__construct()
{
}
//聲明一個獲取類實例的方法
staticfunctiongetInstace()
{
if(self::$db){
returnself::$db;
}else{
//生成自己
self::$db=newself();
returnself::$db;
}
}
}
//錯誤調用方法
//用new實例化private標記構造函數的類會報錯
$db=newDatabase();
//正確獲取實例方法
$db=Database::getInstace();
使用單例模式的好處是,當你在其他地方也要使用到這個類,比如上面的資料庫類。那麼你可以在其它地方直接調用Database::getInstace(),而且該實例只會被生成一次,不會被重復生成,所以不會浪費系統資源。
簡單的說,單例模式生成的實例只被生成一次,而且只負責一個特定的任務。
使用單例模式有下面幾個要求:
1.構造函數需要標記為private(訪問控制:防止外部代碼使用new操作符創建對象),單例類不能在其他類中實例化,只能被其自身實例化;
2.擁有一個保存類的實例的靜態成員變數;
3.擁有一個訪問這個實例的公共的靜態方法(常用getInstance()方法進行實例化單例類,通過instanceof操作符可以檢測到類是否已經被實例化);
4.如果嚴謹的話,還需要創建__clone()方法防止對象被復制(克隆)。(我上面沒創建)
使用單例模式好處,總結:
1、php的應用主要在於資料庫應用, 所以一個應用中會存在大量的資料庫操作, 使用單例模式, 則可以避免大量的new 操作消耗的資源。
2、如果系統中需要有一個類來全局控制某些配置信息, 那麼使用單例模式可以很方便的實現. 這個可以參看ZF的FrontController部分。
3、在一次頁面請求中, 便於進行調試。
參考:http://coderschool.cn/1523.html
⑷ PHP基於單例模式實現的資料庫操作基類
本文實例講述了PHP基於單例模式實現的資料庫操作基類。分享給大家供大家參考,具體如下:
配置文件:
<?php
$db
=
array(
'host'=>'localhost',
'user'=>'root',
'password'=>'',
'database'=>'test',
)
?>
php
資料庫基類:
<?php
class
db
{
public
$conn;
public
static
$sql;
public
static
$instance=null;
private
function
__construct(){
require_once('db.config.php');
$this->conn
=
mysql_connect($db['host'],$db['user'],$db['password']);
if(!mysql_select_db($db['database'],$this->conn)){
echo
"失敗";
};
mysql_query('set
names
utf8',$this->conn);
}
public
static
function
getInstance(){
if(is_null(self::$instance)){
self::$instance
=
new
db;
}
return
self::$instance;
}
/**
*
查詢資料庫
*/
public
function
select($table,$condition=array(),$field
=
array()){
$where='';
if(!empty($condition)){
foreach($condition
as
$k=>$v){
$where.=$k."='".$v."'
and
";
}
$where='where
'.$where
.'1=1';
}
$fieldstr
=
'';
if(!empty($field)){
foreach($field
as
$k=>$v){
$fieldstr.=
$v.',';
}
$fieldstr
=
rtrim($fieldstr,',');
}else{
$fieldstr
=
'*';
}
self::$sql
=
"select
{$fieldstr}
from
{$table}
{$where}";
$result=mysql_query(self::$sql,$this->conn);
$resuleRow
=
array();
$i
=
0;
while($row=mysql_fetch_assoc($result)){
foreach($row
as
$k=>$v){
$resuleRow[$i][$k]
=
$v;
}
$i++;
}
return
$resuleRow;
}
/**
*
添加一條記錄
*/
public
function
insert($table,$data){
$values
=
'';
$datas
=
'';
foreach($data
as
$k=>$v){
$values.=$k.',';
$datas.="'$v'".',';
}
$values
=
rtrim($values,',');
$datas
=
rtrim($datas,',');
self::$sql
=
"INSERT
INTO
{$table}
({$values})
VALUES
({$datas})";
if(mysql_query(self::$sql)){
return
mysql_insert_id();
}else{
return
false;
};
}
/**
*
修改一條記錄
*/
public
function
update($table,$data,$condition=array()){
$where='';
if(!empty($condition)){
foreach($condition
as
$k=>$v){
$where.=$k."='".$v."'
and
";
}
$where='where
'.$where
.'1=1';
}
$updatastr
=
'';
if(!empty($data)){
foreach($data
as
$k=>$v){
$updatastr.=
$k."='".$v."',";
}
$updatastr
=
'set
'.rtrim($updatastr,',');
}
self::$sql
=
"update
{$table}
{$updatastr}
{$where}";
return
mysql_query(self::$sql);
}
/**
*
刪除記錄
*/
public
function
delete($table,$condition){
$where='';
if(!empty($condition)){
foreach($condition
as
$k=>$v){
$where.=$k."='".$v."'
and
";
}
$where='where
'.$where
.'1=1';
}
self::$sql
=
"delete
from
{$table}
{$where}";
return
mysql_query(self::$sql);
}
public
static
function
getLastSql(){
echo
self::$sql;
}
}
$db
=
db::getInstance();
//$list
=
$db->select('demo',array('name'=>'tom','password'=>'ds'),array('name','password'));
//echo
$db->insert('demo',array('name'=>'腳本之家','password'=>'123'));
//echo
$db->update('demo',array("name"=>'xxx',"password"=>'123'),array('id'=>1));
echo
$db->delete('demo',array('id'=>'2'));
db::getLastSql();
echo
"<pre>";
?>
更多關於PHP操作資料庫相關內容感興趣的讀者可查看本站專題:《php+mysql資料庫操作入門教程》、《PHP基於pdo操作資料庫技巧總結》及《php常見資料庫操作技巧匯總》
希望本文所述對大家PHP程序設計有所幫助。
⑸ PHP為什麼以及什麼時候使用單例模式
單例模式確保某個類只有一個實例
1.只能有一個實例。
2.必須自行創建這個實例。
3.必須給其他對象提供這一實例。
那麼為什麼要使用PHP單例模式?
PHP一個主要應用場合就是應用程序與資料庫打交道的場景,在一個應用中會存在大量的資料庫操作,針對資料庫句柄連接資料庫的行為,使用單例模式可以避免大量的new操作。因為每一次new操作都會消耗系統和內存的資源。
優點:
1. 改進系統的設計
2. 是對全局變數的一種改進
缺點:
1. 難於調試
2. 隱藏的依賴關系
3. 無法用錯誤類型的數據覆寫一個單例
⑹ 在php隊列php-resque里頭使用了資料庫的單例模式顯示MySQL server has gone away
PHP的輕量消息隊列php-resque使用說明
消息隊列處理後台任務帶來的問題
項目中經常會有後台運行任務的需求,比如發送郵件時,因為要連接郵件伺服器,往往需要5-10秒甚至更長時間,如果能先給用戶一個成功的提示信息,然後在後台慢慢處理發送郵件的操作,顯然會有更好的用戶體驗。
為了實現類似的需求,Web項目中一般的實現方法是使用消息隊列(Message Queue),比如MemcacheQ,RabbitMQ等等,都是很著名的產品。
消息隊列說白了就是一個最簡單的先進先出隊列,隊列的一個成員就是一段文本。正是因為消息隊列實在太簡單了,當拿著消息隊列時,反而有點無從下手的感覺,因為這僅僅一個發送郵件的任務,就會引申出很多問題:
消息隊列只能存儲字元串類型的數據,如何將一個發送郵件這樣的「任務」,轉換為消息隊列中的一個「消息」?
消息隊列只負責數據的存放與進出,本身不能執行任何程序,那麼我們要如何從消息隊列中一個一個取出數據,再將這些數據轉化回任務並執行。
我們無法預知消息隊列何時會有數據產生,所以我們的任務執行程序還需要具備監控消息隊列的能力,也就是一個常駐後台的守護進程。
一般的Web應用PHP都以cgi方式運行,無法常駐內存。我們知道php還有cli模式,那麼守護進程是否能以php cli來實現,效率如何?
當守護進程運行時,Web應用能否與後台守護進程交互,實現開啟/殺死進程的功能以及獲得進程的運行狀態?
Resque對後台任務的設計與角色劃分
對以上這些問題,目前為止我能找到的最好答案,並不是來自php,而是來自Ruby的項目Resque,正是由於Resque清晰簡單的解決了後台任務帶來的一系列問題,Resque的設計也被Clone到Python、php、NodeJs等語言:比如Python下的pyres以及PHP下的php-resque等等,這里有各種語言版本的Resque實現,而在本篇日誌里,我們當然要以PHP版本為例來說明如何用php-resque運行一個後台任務,可能一些細節方面會與Ruby版有出入,但是本文中以php版為准。
Resque是這樣解決這些問題的:
後台任務的角色劃分
其實從上面的問題已經可以看出,只靠一個消息隊列是無法解決所有問題的,需要新的角色介入。在Resque中,一個後台任務被抽象為由三種角色共同完成:
Job | 任務 : 一個Job就是一個需要在後台完成的任務,比如本文舉例的發送郵件,就可以抽象為一個Job。在Resque中一個Job就是一個Class。
Queue | 隊列 : 也就是上文的消息隊列,在Resque中,隊列則是由Redis實現的。Resque還提供了一個簡單的隊列管理器,可以實現將Job插入/取出隊列等功能。
Worker | 執行者 : 負責從隊列中取出Job並執行,可以以守護進程的方式運行在後台。
那麼基於這個劃分,一個後台任務在Resque下的基本流程是這樣的:
將一個後台任務編寫為一個獨立的Class,這個Class就是一個Job。
在需要使用後台程序的地方,系統將Job Class的名稱以及所需參數放入隊列。
以命令行方式開啟一個Worker,並通過參數指定Worker所需要處理的隊列。
Worker作為守護進程運行,並且定時檢查隊列。
當隊列中有Job時,Worker取出Job並運行,即實例化Job Class並執行Class中的方法。
至此就可以完整的運行完一個後台任務。
在Resque中,還有一個很重要的設計:一個Worker,可以處理一個隊列,也可以處理很多個隊列,並且可以通過增加Worker的進程/線程數來加快隊列的執行速度。
php-resque的安裝
需要提前說明的是,由於涉及到進程的開辟與管理,php-resque使用了php的PCNTL函數,所以只能在Linux下運行,並且需要php編譯PCNTL函數。如果希望用Windows做同樣的工作,那麼可以去找找Resque的其他語言版本,php在Windows下非常不適合做後台任務。
以Ubuntu12.04LTS為例,Ubuntu用apt安裝的php已經默認編譯了PCNTL函數,無需任何配置,以下指令均為root帳號安裝Redis
apt-get install redis-server
安裝Composer
apt-get install curl
cd /usr/local/bin
curl -s http://getcomposer.org/installer | phpchmod a+x composer.phar
alias composer='/usr/local/bin/composer.phar'
使用Composer安裝php-resque
假設web目錄在/opt/htdocs
apt-get install git git-core
cd /opt/htdocs
git clone git://github.com/chrisboulton/php-resque.gitcd php-resque
composer install
php-resque的使用
編寫一個Worker
其實php-resque已經給出了簡單的例子, demo/job.php文件就是一個最簡單的Job:
class PHP_Job
{
public function perform()
{
sleep(120);
fwrite(STDOUT, 'Hello!');
}
}
這個Job就是在120秒後向STDOUT輸出字元Hello!
在Resque的設計中,一個Job必須存在一個perform方法,Worker則會自動運行這個方法。
將Job插入隊列
php-resque也給出了最簡單的插入隊列實現 demo/queue.php:
if(empty($argv[1])) {
die('Specify the name of a job to add. e.g, php queue.php PHP_Job');}
require __DIR__ . '/init.php';
date_default_timezone_set('GMT');
Resque::setBackend('127.0.0.1:6379');
$args = array(
'time' => time(),
'array' => array(
'test' => 'test',
),
);
$jobId = Resque::enqueue('default', $argv[1], $args, true);echo "Queued job ".$jobId."\n\n";
在這個例子中,queue.php需要以cli方式運行,將cli接收到的第一個參數作為Job名稱,插入名為'default'的隊列,同時向屏幕輸出剛才插入隊列的Job Id。在終端輸入:
php demo/queue.php PHP_Job
結果可以看到屏幕上輸出:
Queued job 即Job已經添加成功。注意這里的Job名稱與我們編寫的Job Class名稱保持一致:PHP_Job查看Job運行情況
php-resque同樣提供了查看Job運行狀態的例子,直接運行:
php demo/check_status.php 可以看到輸出為:
Tracking status of . Press [break] to stop.
Status of is: 1我們剛才創建的Job狀態為1。在Resque中,一個Job有以下4種狀態:
Resque_Job_Status::STATUS_WAITING = 1; (等待)Resque_Job_Status::STATUS_RUNNING = 2; (正在執行)Resque_Job_Status::STATUS_FAILED = 3; (失敗)Resque_Job_Status::STATUS_COMPLETE = 4; (結束)因為沒有Worker運行,所以剛才創建的Job還是等待狀態。
運行Worker
這次我們直接編寫demo/resque.php:
<?php
date_default_timezone_set('GMT');
require 'job.php';
require '../bin/resque';
可以看到一個Worker至少需要兩部分:
可以直接包含Job類文件,也可以使用php的自動載入機制,指定好Job Class所在路徑並能實現自動載入包含Resque的默認Worker: bin/resque
在終端中運行:
QUEUE=default php demo/resque.php
前面的QUEUE部分是設置環境變數,我們指定當前的Worker只負責處理default隊列。也可以使用QUEUE=* php demo/resque.php
來處理所有隊列。
運行後輸出為
#!/usr/bin/env php
*** Starting worker
用ps指令檢查一下:
ps aux | grep resque
可以看到有一個php的守護進程已經在運行了
1000 4607 0.0 0.1 74816 11612 pts/3 S+ 14:52 0:00 php demo/resque.php再使用之前的檢查Job指令
php demo/check_status.php 2分鍾後可以看到
Status of is: 4任務已經運行完畢,同時屏幕上應該可以看到輸出的Hello!
至此我們已經成功的完成了一個最簡單的Resque實例的全部演示,更復雜的情況以及遺留的問題會在下一次的日誌中說明。
⑺ php的單例模式有什麼具體好處具體在哪裡實現面試的時候讓人問到..求解
單例不只是PHP中有,是面向對象類語言都有的概念。
你說的是做用,是從語言層面上。只有一個實例。
我覺得面試官要問的是實際使用的含義,對於整個程序設計而言的好處。
我本身也不是什麼高手,覺得我說的不對輕噴。
我也用過PHP的TP框架,但是用的很淺,沒有體會到有什麼特別的。
我說說java的spring框架,它的bean實例化是單例的,struts2也支持選擇是否單例。
它能節約內存開銷,這是最明顯的,一個工具類,或者一個服務類,單例下,一個實例足夠,並不需要創建N此,無故的浪費掉內存。
從設計上而言,一個只需要實例化一次就足夠的類,設計為單例,這樣可以做到從設計上而言更清晰
⑻ PHP設計模式之單例模式
單例模式
:使得類的一個對象成為系統中的唯一實例.
PHP中使用單例模式最常見的就是資料庫操作了。避免在系統中有多個連接資料庫的操作,浪費系統資源的現象,就可以使用單例模式。每次對資料庫操作都使用一個實例。
簡單示例
class
AClass
{
//
用來存儲自己實例
public
static
$instance;
//
私有化構造函數,防止外界實例化對象
private
function
__construct()
{}
//
私有化克隆函數,防止外界克隆對象
private
function
__clone()
{}
//
靜態方法,單例訪問統一入口
public
static
function
getInstance()
{
if
(!(self::$instance
instanceof
self)){
self::$instance
=
new
self();
}
return
self::$instance;
}
//
test
public
function
test()
{
return
"done";
}
//
私有化克隆函數,防止外界克隆對象
private
function
__clone()
{}
}
class
BClass
extends
AClass{
}
//
獲取實例
$aclass
=
AClass::getInstance();
$bclass
=
BClass::getInstance();
//
調用方法
echo
$aclass->test();
對一些比較大型的應用來說,可能連接多個資料庫,那麼不同的資料庫公用一個對象可能會產生問題,比如連接句柄的分配等,我們可以通過給$instance變成數組,通過不同的參數來控制
簡單示例
class
DB
{
//
用來存儲自己實例
public
static
$instance
=
array();
public
$conn;
//
私有化構造函數,防止外界實例化對象
private
function
__construct($host,
$username,
$password,
$dbname,
$port)
{
$this->conn
=
new
mysqli($host,
$username,
$password,
$dbname,
$port);
}
//
靜態方法,單例訪問統一入口
public
static
function
getInstance($host,
$username,
$password,
$dbname,
$port)
{
$key
=
$host.":".$port;
if
(!(self::$instance[$key]
instanceof
self)){
self::$instance[$key]
=
new
self($host,
$username,
$password,
$dbname,
$port);#實例化
}
return
self::$instance[$key];
}
//query
public
function
query($ql)
{
return
$this->conn->query($sql);
}
//
私有化克隆函數,防止外界克隆對象
private
function
__clone()
{}
//釋放資源
public
function
__destruct(){
$this->conn->close();
}
}
⑼ 為什麼要使用PHP單例模式及應用實例
單例模式顧名思義,就是只有一個實例。作為對象的創建模式, 單例模式確保某一個類只有一個實例,而且自行實例化並向整個系統提供這個實例,這個類我們稱之為單例類。單例模式的要點有三個:一是某個類只能有一個實例;二是它必須自行創建這個實例;三是它必須自行向整個系統提供這個實例。下面我們討論下為什麼要使用PHP單例模式?多數人都是從單例模式的字面上的意思來理解它的用途, 認為這是對系統資源的節省, 可以避免重復實例化, 是一種"計劃生育". 而PHP每次執行完頁面都是會從內存中清理掉所有的資源. 因而PHP中的單例實際每次運行都是需要重新實例化的, 這樣就失去了單例重復實例化的意義了. 單單從這個方面來說, PHP的單例的確有點讓各位失望. 但是單例僅僅只有這個功能和應用嗎? 答案是否定的,我們一起來看看。1. php的應用主要在於資料庫應用, 所以一個應用中會存在大量的資料庫操作, 在使用面向對象的方式開發時(廢話), 如果使用單例模式, 則可以避免大量的new 操作消耗的資源。2. 如果系統中需要有一個類來全局控制某些配置信息, 那麼使用單例模式可以很方便的實現. 這個可以參看zend Framework的FrontController部分。
⑽ php中連接資料庫,使用單例模式遇到的問題
當然是重新連接了,你是跳轉不是包含。
跳轉兩者之間共享值要專門的傳值操作,cookie\
session\
POST/GET
\靜態輸出