❶ 如何在Windows下配置搭建php環境
一、安裝Apache,配置成功一個普通網站伺服器
運行下載好的「apache_2.0.55-win32-x86-no_ssl.msi」,出現如下界面:
❷ 如何安裝運行PHP網站
搭建PHP本地環境前言
【本地環境就是你的網站還沒有上線,但是想在自己電腦看一下網站搭建後的效果。你在自己電腦做了一個可以看效果的環境。也就是測試環境。】
目前80%以上的網站都是使用xunruicms模版(PHP語言編寫的),所以這里只教大家建立PHP本地環境搭建。
新手做網站,還要上線,輸入域名可以訪問很新奇,但得先看這篇"搭建PHP本地環境並運行xunruicms網站",有了這個基礎再看下一篇"網站上線"會容易得多。PHP本地環境搭建就是讓你熟悉網站上線的基本功,免得你正式上線手忙腳亂一堆事情,一會兒就放棄了。我也是一步步來的,我盡量寫得很細,讓大家跟著我操作就可以。
xunruicms建站步驟主要分為三步:①搭建PHP環境,②建立資料庫,③安裝xunruicms網站
PHP環境搭建
PHP環境搭建使用工具(大學里常用的工具):
WAMPserver
XAMPP
這兩個工具任選一個就可以了。這兩個工具都是Windows系統下的安裝包,linux環境無法使用,裡面集成了APACH, MYSQL, PHPADMIN不需要自己一個個安裝然後配置。安裝包都是exe文件,基本都是一鍵安裝,很簡單。我使用的是WAMPserver.
在官網下載 我下載的是3.1.4版本的,這一版本很好,裡面很多配置都不需要自己重新配。
下載安裝
下載好後直接雙擊打開
80埠被Apache正常使用,沒有被佔用。
配置資料庫
點擊"W"標志,點擊"PHPMYADMIN
❸ PHP項目案例分析的前言
學習語言的目的是為了開發項目,很多初學者對於學習技術沒有問題,但要真正開發項目,就會感到迷茫和手足無措。而對於即將畢業的學生來說,提交的畢業設計又會讓他們感到焦頭爛額。
為了幫助讀者解決這些問題,引導讀者學有所用,特編寫了本書,內容涉及PHP開發的主流開發技術,並以最簡單通俗的方式向讀者介紹如何開發Web項目。相信通過本書的學習,讀者會在PHP項目開發的道路上積累更多的實戰經驗,掌握項目開發的方法。同時,也為正在忙於畢業設計的同學提供了一條捷徑。
如果讀者在學習的過程中遇到問題,可以通過QQ、論壇等方式與我們聯系,我們會力爭排除讀者在PHP學習過程中遇到的各種障礙。
本書內容
本書分為8章,其中包括6個實用項目和2個畢業設計。實用項目包括圖書信息管理系統、俊羽會議管理系統、夢幻網路日記、企業網站系統、明日網上書店和問鼎辦公自動化系統的設計;畢業設計包括圖書館管理系統和電子商務網站的設計。
本書特色
* 技術豐富:本書從實際應用的角度出發,運用最簡潔、最實用的技術開發最流行的項目。如PHP操作MySQL資料庫、Smarty模板、PDO和ADODB資料庫抽象層等技術。
* 橫向擴展:本書屬於PHP系列圖書的一部分,在經過了基礎、範例和典型模塊等內容的學習後,以此來檢驗讀者的學習成果,體會Web項目開發的過程,積累實戰經驗。
* 講解到位:本書對每個項目中最有價值的部分進行了剖析,以達到畫龍點睛的目的。
* 贈送項目源代碼和畢業設計論文:書中所有項目均提供有源代碼,用戶在開發中可以快速借鑒或應用,並且提供了兩篇畢業設計論文,以供參考。
* 提供多節視頻錄像:本書提供了多節的項目開發視頻錄像,讀者可以邊看邊學,快速提高。
本書配套資源
本書提供了內容豐富的配套資源,包括自學視頻、源程序、素材,以及模塊庫、案例庫、題庫、素材庫等多項輔助內容,讀者朋友可以通過如下方式獲取。
第1種方式:
(1)登錄清華大學出版社的網站,在網頁右上角的搜索文本框中輸入本書書名(注意區分大小寫和留出空格),或者輸入本書關鍵字,或者輸入本書ISBN號(注意去掉ISBN號間隔線「-」),單擊「搜索」按鈕。
(2)找到本書後單擊超鏈接,在該書的網頁下側單擊「網路資源」超鏈接,即可下載。
第2種方式:
訪問本書的新浪微博PHPbook,找到配套資源的鏈接地址進行下載。
本書約定
* 項目使用方法
用戶在學習本書過程中,可以從配套資源中復製程序,去掉其只讀屬性。有些項目需要使用相應的資料庫或第三方資源,此類程序在使用前需要進行相應配置,詳細使用方式可參考本書的配套資源使用說明書。此外,如果用戶直接將本書內容用於商業用途,由此產生的不良後果由用戶自己承擔。
* 部分項目只給出關鍵代碼
由於篇幅限制,書中有些模塊只給出了關鍵代碼,完整代碼可參見配套資源項目程序。
讀者人群
本書非常適合以下人員閱讀:
* 從事PHP編程行業的開發人員
* 有一定語言基礎,想進一步提高技能的人員
* 大中專院校的老師和學生
* 即將走上工作崗位的大學畢業生
* 相關培訓機構的老師和學員
* PHP編程愛好者
❹ 基於php的在線考試系統 引言怎麼寫
管理系統
明確的,我知道設計的
❺ PhpStorm軟體求提供一款中文免費版,謝謝!
《PhpStorm 2020.1中文破解版》網路網盤資源免費下載:
鏈接: https://pan..com/s/1GTg54RahK6cGscMTr0fudg
PhpStorm 2020.1是由JetBrains公司研發的一款功能豐富的PHP集成開發環境,是PhpStorm編程軟體系列的最新版本,深厚世界各地PHP程序員的喜歡,很多工程師都用它來開發和部署網站。該軟體擁有強大的智能編碼輔助功能,包含動態錯誤檢查、零配置調試、擴展的HTML、代碼重構等等。
❻ php 框架 怎麼使用回調函數
前言
最近在開發一個PHP系統,為了提高系統的擴展性,我想在系統中加入類似Javascript的事件處理機制,例如:我想在一篇新聞被添加以後,我想記錄一下日誌,用類似Javascript的代碼,應該是這樣寫的:
function fnCallBack( $news )
{
//將$news的信息記錄到日誌中
writeLog( $news->getTitle().' has been added successfully!');
}
$newsEventManager->addEventListener( 'add' , fnCallBack );
其中,fnCallBack函數是回調函數,addEventListener表示監聽newsEventManager的add事件。當一篇news被add以後,系統就會調用fnCallBack函數,從而完成writeLog的動作。
但是,PHP中的函數傳遞方法和Javascript有很大的不同。在Javascript中,函數也是對象,它可以很方便的當作參數傳遞,但是PHP不行。
$newsEventManager->addEventListener( 'add' , fnCallBack );
上面這行代碼中的fnCallBack,看上去好像是那個函數的句柄,但實質上它是一個字元串,並不是我們所要的函數。
為了實現我們的事件模型,有必要研究一下PHP的回調函數的實現方法。
全局函數的回調
這里的全局函數的意思,是直接使用function定義的函數,它不包含在任何對象或類之中。請看下面的例子
示例代碼
function fnCallBack( $msg1 , $msg2 )
{
echo 'msg1:'.$msg1;
echo "<br />\n";
echo 'msg2:'.$msg2;
}
$fnName = "fnCallBack";
$params = array( 'hello' , 'world' );
call_user_func_array( $fnName , $params );
代碼說明:
這里使用了PHP內置的函數call_user_func_array來進行調用。call_user_func_array有兩個參數,第1個參數是一個字元串,表示要調用的函數名,第2個參數是一個數組,表示參數列表,按照順序依次會傳遞給要調用的函數。
效果如下:
類的靜態方法的回調
如果我們要回調的方法,是一個類的靜態方法,那怎麼辦呢?我們依然可以利用PHP內置的call_user_func_array方法來進行調用,請看示例:
示例代碼:
class MyClass
{
public static function fnCallBack( $msg1 , $msg2 )
{
echo 'msg1:'.$msg1;
echo "<br />\n";
echo 'msg2:'.$msg2;
}
}
$className = 'MyClass';
$fnName = "fnCallBack";
$params = array( 'hello' , 'world' );
call_user_func_array( array( $className , $fnName ) , $params );
代碼說明:
這段代碼和第1種方法的代碼很相似,我們將類名(MyClass)也作為call_user_func_array的第1個參數傳遞進去,就可以實現類的靜態方法的回調了。注意,這時call_user_func_array的第1個參數是一個數組了,數組的第1個元素是類名,第二個元素是要調用的函數名
運行結果:
(其實和第1種方法的結果是一樣的 ^_^ )
繼續研究
如果我用這種方法調用一個類的非靜態方法(也就是把static去掉),會出現什麼結果呢?請看下面代碼
class MyClass
{
public function fnCallBack( $msg1 , $msg2 )
{
echo 'msg1:'.$msg1;
echo "<br />\n";
echo 'msg2:'.$msg2;
}
}
$className = 'MyClass';
$fnName = "fnCallBack";
$params = array( 'hello' , 'world' );
call_user_func_array( array( $className , $fnName ) , $params );
運行結果
和前面的結果還是一樣的。。。
現在我為這個類添加一點屬性,並在方法中引用
class MyClass
{
private $name = 'abc';
public function fnCallBack( $msg1 , $msg2 )
{
echo 'object name:'.$this->name;
echo "<br />\n";
echo 'msg1:'.$msg1;
echo "<br />\n";
echo 'msg2:'.$msg2;
}
}
$className = 'MyClass';
$fnName = "fnCallBack";
$params = array( 'hello' , 'world' );
call_user_func_array( array( $className , $fnName ) , $params );
運行結果
出現解析錯誤,提示$this沒有在對象環境下出現,說明這個方法不能用類來調用,而是要用對象來調用。那我們就修改一下代碼,創建一個對象:
class MyClass
{
public function fnCallBack( $msg1 , $msg2 )
{
echo 'msg1:'.$msg1;
echo "<br />\n";
echo 'msg2:'.$msg2;
}
}
$myobj = new MyClass();
$className = 'myobj';
$fnName = "fnCallBack";
$params = array( 'hello' , 'world' );
call_user_func_array( array( $className , $fnName ) , $params );
運行結果:
提示call_user_func_array的第1個參數非法,也就是說,調用失敗。看來我們不能用call_user_func_array方法來回調一個對象的方法了,那麼如何實現對象方法的回調的?
對象的方法的回調
我先用最原始的字元串形式的調用方法嘗試了一下,如下所示:
class MyClass
{
private $name = 'abc';
public function fnCallBack( $msg1 = 'default msg1' , $msg2 = 'default msg2' )
{
echo 'object name:'.$this->name;
echo "<br />\n";
echo 'msg1:'.$msg1;
echo "<br />\n";
echo 'msg2:'.$msg2;
}
}
$myobj = new MyClass();
$fnName = "fnCallBack";
$params = array( 'hello' , 'world' );
$myobj->$fnName();
成功了,輸出結果
調用是成功了,不過如何把參數params傳給這個方法呢,如果把params直接傳進去,那麼它會作為1個參數,怎麼把params拆開來傳進去呢?
查了下PHP手冊,找到了create_function函數,這個方法可以用字元串來創建一個匿名函數,好,有思路了,可以創建一個匿名的函數,在這個匿名函數中,調用我們的回調函數,並把參數傳進去。
我先手動創建一個匿名函數anonymous,在這個函數中,用前面試出來的方法調用回調函數,如下所示:
class MyClass
{
private $name = 'abc';
public function fnCallBack( $msg1 = 'default msg1' , $msg2 = 'default msg2' )
{
echo 'object name:'.$this->name;
echo "<br />\n";
echo 'msg1:'.$msg1;
echo "<br />\n";
echo 'msg2:'.$msg2;
}
}
$myobj = new MyClass();
$fnName = "fnCallBack";
$params = array( 'hello' , 'world' );
function anonymous()
{
global $myobj;
global $fnName;
global $params;
$myobj->$fnName( $params[0] , $params[1] );
}
anonymous();
成功了,可以看到,對象的屬性name也輸出來了
然後,我用create_function來創建這個匿名函數,同時,代碼中的params[0],params[1]應該是動態生成的,代碼如下:
$strParams = '';
$strCode = 'global $myobj;global $fnName;global $params;$myobj->$fnName(';
for ( $i = 0 ; $i < count( $params ) ; $i ++ )
{
$strParams .= ( '$params['.$i.']' );
if ( $i != count( $params )-1 )
{
$strParams .= ',';
}
}
$strCode = $strCode.$strParams.");";
$anonymous = create_function( '' , $strCode);
$anonymous();
這段代碼可以定義一個匿名函數,並保存在$anonymous變數中,最後調用這個$anonymous,實現了方法的回調,如圖
PHP事件模型(觀察者模式)的實現思路
至此,PHP中的3種常見的函數類型(全局函數,類靜態函數,對象的方法)都可以回調了,可以實現文章一開始說的事件模型了 :)
事件模型模仿Firefox的Javascript實現,有3個方法,分別是
addEventListener:注冊一個事件上的響應回調函數
removeEventListener:刪除一個事件上的響應回調函數
fire:觸發一個事件,也就是循環調用所有響應這個事件的回調函數
不過,由於第2、第3種方法需要傳遞上下文(也就是類名和對象名),所以addEventListener和removeEventListener應該有3個參數,我是這樣設計的:
function addEventListener( $evtName , $handler , $scope = null )
第1個參數表示事件名,字元串類型
第2個參數表示回調函數名,字元串類型
第3個參數$scope是上下文環境,一共有3種類型,null表示傳入的handler函數是一個全局函數,字元串類型表示傳入的handler函數是scope類的靜態函數,對象類型表示傳入的scope是一個對象,handler函數是對象的一個方法。
function fire( $evtName , $params = null )
這個方法內,會讀取出所有響應evtName的handler,然後判斷它對應的scope,如果是null,則用本文第1種方法回調,如果是字元串,則用本文第2種方法回調,如果是對象,則用本文第3種方法回調。這樣,一個PHP的事件模型就可以實現了,而且可以將回調函數放在某個對象中。
❼ Android和PHP開發最佳實踐的圖書目錄
前言第一篇 准備篇第1章學前必讀 11.1移動互聯網時代的來臨 11.2為何選擇Android和PHP 21.3如何學習Android和PHP 31.3.1如何學習Android 31.3.2如何學習PHP 41.3.3同時學好Android和PHP 41.4小結 5第2章Android開發准備 62.1Android背景知識 62.2Android系統框架 82.3Android應用框架 112.3.1活動(Activity) 122.3.2消息(Intent) 142.3.3視圖(View) 162.3.4任務(Task) 172.4Android系統四大組件 192.4.1活動(Activity) 202.4.2服務(Service) 212.4.3廣播接收器(Broadcast Receiver) 232.4.4內容提供者(Content Provider) 242.5Android上下文 252.5.1界面上下文(Activity Context) 252.5.2應用上下文(Application Context) 272.6Android數據存儲 282.6.1應用配置(Shared Preferences) 282.6.2 本地文件(Files) 292.6.3資料庫(SQLite) 302.7Android應用界面 312.7.1控制項屬性 312.7.2布局(Layout) 332.7.3事件(Event) 372.7.4菜單(Menu) 392.7.5主題(Theme) 412.7.6對話框(Dialog) 422.8Android圖形界面 432.8.1畫筆(Paint) 432.8.2畫布(Canvas) 442.8.3 基礎幾何圖形 462.8.4常見圖形變換 472.9Android動畫效果 502.9.1逐幀動畫(Frame Animation) 502.9.2補間動畫(Tween Animation) 512.10Android開發環境 522.10.1開發環境的搭建 532.10.2首個Android項目 582.10.3使用DDMS調試工具 632.11小結 64第3章PHP開發准備 653.1PHP開發基礎 653.1.1PHP語言簡介 653.1.2PHP語法簡介 663.1.3PHP開發起步 683.1.4PHP面向對象編程 753.1.5PHP的會話 783.2PHP開發環境 803.2.1開發環境的搭建 803.2.2安裝配置Xampp 813.2.3管理Apache 833.2.4管理MySQL 843.3使用JSON通信 873.4常用PHP開發框架 883.5認識Smarty模板引擎 903.6開發框架簡介 933.6.1框架的特點和優勢 943.6.2框架的基礎目錄結構 943.6.3框架MVC思路講解 973.6.4框架MVC實例分析 993.7小結 108第二篇實戰篇第4章實例產品設計 1094.1為何選擇微博 1094.2開發前的准備 1104.2.1選擇開發模式 1104.2.2了解項目策劃 1114.2.3了解原型設計 1124.3功能模塊設計 1124.4應用界面設計 1144.5應用架構設計 1154.6通信協議定義 1164.7資料庫結構設計 1184.8小結 120第5章程序架構設計 1215.1服務端程序架構設計 1215.1.1基礎框架設計 1225.1.2調試框架設計 1275.1.3核心類庫設計 1305.1.4服務端的MVC與SOA 1365.2客戶端程序架構設計 1365.2.1基礎框架設計 1375.2.2核心類包設計 1385.2.3Android應用的MVC 1425.3客戶端界面架構設計 1425.3.1界面框架設計 1435.3.2主要界面設計 1445.4小結 146第6章服務端開發 1476.1開發入門 1476.1.1介面程序開發 1476.1.2調試框架開發 1516.1.3生成介面文檔 1556.2驗證介面 1566.2.1用戶登錄介面 1566.2.2用戶登出介面 1606.3用戶介面 1626.3.1新建用戶介面 1626.3.2更新用戶信息介面 1646.3.3查看用戶信息介面 1656.3.4添加粉絲介面 1676.3.5刪除粉絲介面 1716.4微博介面 1726.4.1發表微博介面 1726.4.2查看微博介面 1746.4.3微博列表介面 1766.5評論介面 1806.5.1發表評論介面 1806.5.2評論列表介面 1826.6圖片介面 1846.6.1用戶頭像介面 1856.6.2頭像列表介面 1886.7通知介面 1896.8Web版介面 1926.8.1Web版UI界面(jQuery Mobile) 1936.8.2Web版地圖介面 1956.9小結 196第7章客戶端開發 1987.1開發入門 1987.1.1開發思路梳理 1987.1.2掌握應用配置文件 2007.1.3常規程序開發與調試 2117.2界面布局和行為控制 2217.2.1使用Layout布局 2217.2.2使用Merge整合界面 2247.2.3使用Event控制用戶行為 2267.2.4使用Intent控制界面切換 2287.3網路通信模塊 2317.3.1使用HttpClient進行網路通信 2317.3.2支持CMWAP網路接入方式 2377.3.3使用JSON庫為消息解碼 2407.3.4使用Toast消息提示 2457.4非同步任務模塊 2477.4.1進程和線程 2477.4.2任務創建Thread 2497.4.3任務處理Handler 2557.4.4使用非同步任務AsyncTask 2577.5全局功能模塊 2597.5.1全局UI基類 2597.5.2全局Menu菜單 2647.5.3全局Dialog窗口 2657.5.4使用Service獲取通知 2667.5.5使用Notification顯示通知 2707.6用戶登錄界面 2737.6.1界面程序邏輯 2737.6.2使用TextView 2737.6.3使用EditText 2747.6.4使用Button 2767.6.5使用Shape和Selector 2777.6.6使用CheckBox 2797.6.7使用SharedPreference 2807.7微博列表界面 2817.7.1界面程序邏輯 2817.7.2使用ListView 2867.7.3使用ImageView 2907.7.4使用draw9patch 2927.7.5非同步獲取遠程圖片 2947.7.6使用SdCard緩存圖片 2977.7.7使用SQLite緩存數據 3007.8我的微博列表 3037.8.1界面程序邏輯 3037.8.2使用ScrollView 3097.8.3使用自定義微博列表 3107.9微博文章界面 3137.9.1界面程序邏輯 3137.9.2界面布局進階(綜合使用UI控制項) 3197.9.3發表評論功能實現 3227.9.4發表微博功能實現 3267.10用戶配置界面 3287.10.1界面程序邏輯 3287.10.2使用自定義選項列表 3337.10.3修改簽名功能實現 3347.10.4更換頭像功能實現 3347.11網頁界面開發 3407.11.1界面程序邏輯 3407.11.2使用WebView 3417.11.3使用ProgressDialog 3437.11.4使用WebView的重寫和回調 3467.11.5網頁地圖實例分析 3487.12小結 349第三篇優化篇第8章性能分析 3518.1關於性能測試 3518.1.1服務端壓力測試 3528.1.2客戶端性能測試 3598.2瓶頸 3648.2.1服務端瓶頸分析 3658.2.2客戶端瓶頸分析 3668.3優化的思路 3668.4小結 367第9章 服務端優化 3689.1優化PHP程序 3689.1.1優化PHP代碼 3689.1.2優化Session機制 3719.1.3使用緩存中間件 3739.1.4使用APC加速 3769.2優化數據傳輸 3779.2.1優化JSON協議 3779.2.2使用gzip壓縮 3799.3其他優化 3809.3.1伺服器優化 3809.3.2資料庫優化 3839.3.3網路優化 3869.4小結 386第10章客戶端優化 38710.1優化Android程序 38710.1.1優化Java代碼 38710.1.2非同步獲取數據 39110.1.3文件資源緩存 39110.1.4資料庫緩存 39210.2避免內存泄露 39210.2.1Android內存管理 39210.2.2如何判斷內存泄露 39310.2.3常見內存泄露的處理 39510.3優化Android UI 39610.3.1模板代碼優化 39610.3.2關於布局優化 39710.3.3使用Hierarchy Viewer工具 40210.4其他優化 40310.4.1優化圖片 40310.4.2優化APK包 40310.4.3使用keytool和jarsigner簽名 40410.4.4使用zipalign優化 40710.5小結 408第四篇進階篇第11章Android特色功能開發 40911.1使用Google Map API 40911.2使用LBS功能 41411.3使用感測器 41911.4使用攝像頭 42211.5多媒體開發 43111.6語音識別 43911.7小結 441第12章Android NDK開發 44212.1NDK開發基礎 44212.1.1使用NDK的原因 44212.1.2使用NDK調用C或C++ 44312.1.3Android . mk 和 Application . mk 44512.2NDK開發入門 44812.2.1開發環境搭建 44812.2.2首個NDK項目 44912.3小結 456第13章Android游戲開發 45713.1手游開發基礎 45713.1.1手游開發思路解析 45713.1.2貪食蛇和飛船游戲實例 46213.1.3認識Android游戲引擎 46413.1.4使用OpenGL和OpenGL ES 46613.1.5使用RenderScript 47213.2手游開發進階 47413.2.1認識Cocos2d-x 47513.2.2架設Cocos2d-x開發環境 47513.2.3首個Cocos2d-x項目 47513.2.4認識Unity 3D 48713.3小結 489附錄AHush Framework框架實例源碼部署 490附錄B微博應用實例源碼部署 495
❽ php和go語言哪個好
前言
最近工作中遇到的一個場景,php項目中需要使用一個第三方的功能,而恰好有一個用Golang寫好的類庫。那麼問題就來了,要如何實現不同語言之間的通信呢?下面就來一起看看吧。
常規的方案
1、 用Golang寫一個http/TCP服務,php通過http/TCP與Golang通信
2、將Golang經過較多封裝,做為php擴展。
3、PHP通過系統命令,調取Golang的可執行文件
存在的問題
1、http請求,網路I/O將會消耗大量時間
2、需要封裝大量代碼
3、PHP每調取一次Golang程序,就需要一次初始化,時間消耗很多
優化目標
1、Golang程序只初始化一次(因為初始化很耗時)
2、所有請求不需要走網路
3、盡量不大量修改代碼
解決方案
1、簡單的Golang封裝,將第三方類庫編譯生成為一個可執行文件
2、PHP與Golang通過雙向管道通信
使用雙向管道通信優勢
1:只需要對原有Golang類庫進行很少的封裝
2:性能最佳 (IPC通信是進程間通信的最佳途徑)
3:不需要走網路請求,節約大量時間
4:程序只需初始化一次,並一直保持在內存中
具體實現步驟
1:類庫中的原始調取demo
package main
import (
"fmt"
"github.com/yanyiwu/gojieba"
"strings"
)
func main() {
x := gojieba.NewJieba()
defer x.Free()
s := "小明碩士畢業於中國科學院計算所,後在日本京都大學深造"
words := x.CutForSearch(s, true)
fmt.Println(strings.Join(words, "/"))
}
保存文件為main.go,就可以運行
2:調整後代碼為:
package main
import (
"bufio"
"fmt"
"github.com/yanyiwu/gojieba"
"io"
"os"
"strings"
)
func main() {
x := gojieba.NewJieba(
"/data/tmp/jiebaDict/jieba.dict.utf8",
"/data/tmp/jiebaDict/hmm_model.utf8",
"/data/tmp/jiebaDict/user.dict.utf8"
)
defer x.Free()
inputReader := bufio.NewReader(os.Stdin)
for {
s, err := inputReader.ReadString('\n')
if err != nil && err == io.EOF {
break
}
s = strings.TrimSpace(s)
if s != "" {
words := x.CutForSearch(s, true)
fmt.Println(strings.Join(words, " "))
} else {
fmt.Println("get empty \n")
}
}
}
只需要簡單的幾行調整,即可實現:從標准輸入接收字元串,經過分詞再輸出
測試:
# go build test
# ./test
# //等待用戶輸入,輸入」這是一個測試「
# 這是 一個 測試 //程序
3:使用cat與Golang通信做簡單測試
//准備一個title.txt,每行是一句文本
# cat title.txt | ./test
正常輸出,表示cat已經可以和Golang正常交互了
4:PHP與Golang通信
以上所示的cat與Golang通信,使用的是單向管道。即:只能從cat向Golang傳入數據,Golang輸出的數據並沒有傳回給cat,而是直接輸出到屏幕。但文中的需求是:php與Golang通信。即php要傳數據給Golang,同時Golang也必須把執行結果返回給php。因此,需要引入雙向管道。
在PHP中管道的使用:popen("/path/test") ,具體就不展開說了,因為此方法解決不了文中的問題。
雙向管道:
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w")
);
$handle = proc_open(
'/webroot/go/src/test/test',
$descriptorspec,
$pipes
);
fwrite($pipes['0'], "這是一個測試文本\n");
echo fgets($pipes[1]);
解釋:使用proc_open打開一個進程,調用Golang程序。同時返回一個雙向管道pipes數組,php向$pipe['0']中寫數據,從$pipe['1']中讀數據。
好吧,也許你已經發現,我是標題檔,這里重點要講的並不只是PHP與Golang如何通信。而是在介紹一種方法: 通過雙向管道讓任意語言通信。(所有語言都會實現管道相關內容)
測試:
通過對比測試,計算出各個流程佔用的時間。下面提到的title.txt文件,包含100萬行文本,每行文本是從b2b平台取的商品標題
1: 整體流程耗時
time cat title.txt | ./test > /dev/null
耗時:14.819秒,消耗時間包含:
進程cat讀出文本
通過管道將數據傳入Golang
Golang處理數據,將結果返回到屏幕
2:計算分詞函數耗時。方案:去除分詞函數的調取,即:注釋掉Golang源代碼中的調取分詞那行的代碼
time cat title.txt | ./test > /dev/null
耗時:1.817秒時間,消耗時間包含:
進程cat讀出文本
通過管道將數據傳入Golang
Golang處理數據,將結果返回到屏幕
分詞耗時 = (第一步耗時) - (以上命令所耗時)
分詞耗時 : 14.819 - 1.817 = 13.002秒
3:測試cat進程與Golang進程之間通信所佔時間
time cat title.txt > /dev/null
耗時:0.015秒,消耗時間包含:
進程cat讀出文本
通過管道將數據傳入Golang
go處理數據,將結果返回到屏幕
管道通信耗時:(第二步耗時) - (第三步耗時)
管道通信耗時: 1.817 - 0.015 = 1.802秒
4:PHP與Golang通信的時間消耗
編寫簡單的php文件:
<?php
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w")
);
$handle = proc_open(
'/webroot/go/src/test/test',
$descriptorspec,
$pipes
);
$fp = fopen("title.txt", "rb");
while (!feof($fp)) {
fwrite($pipes['0'], trim(fgets($fp))."\n");
echo fgets($pipes[1]);
}
fclose($pipes['0']);
fclose($pipes['1']);
proc_close($handle);
流程與上面基本一致,讀出title.txt內容,通過雙向管道傳入Golang進程分詞後,再返回給php (比上面的測試多一步:數據再通過管道返回)
time php popen.php > /dev/null
耗時:24.037秒,消耗時間包含:
進程PHP讀出文本
通過管道將數據傳入Golang
Golang處理數據
Golang將返回結果再寫入管道,PHP通過管道接收數據
將結果返回到屏幕
結論:
1 :整個分詞過程中的耗時分布
使用cat控制邏輯耗時: 14.819 秒
使用PHP控制邏輯耗時: 24.037 秒(比cat多一次管道通信)
單向管道通信耗時: 1.8 秒
Golang中的分詞函數耗時: 13.002 秒
2:分詞函數的性能: 單進程,100萬商品標題分詞,耗時13秒
以上時間只包括分詞時間,不包括詞典載入時間。但在本方案中,詞典只載入一次,所以載入詞典時間可以忽略(1秒左右)
3:PHP比cat慢 (這結論有點多餘了,呵呵)
語言層面慢: (24.037 - 1.8 - 14.819) / 14.819 = 50%
單進程對比測試的話,應該不會有哪個語言比cat更快。
相關問題:
1:以上Golang源碼中寫的是一個循環,也就是會一直從管道中讀數據。那麼存在一個問題:是不是php進程結束後,Golang的進程還會一直存在?
管道機制自身可解決此問題。管道提供兩個介面:讀、寫。當寫進程結束或者意外掛掉時,讀進程也會報錯,以上Golang源代碼中的err邏輯就會執行,Golang進程結束。
但如果PHP進程沒有結束,只是暫時沒有數據傳入,此時Golang進程會一直等待。直到php結束後,Golang進程才會自動結束。
2:能否多個php進程並行讀寫同一個管道,Golang進程同時為其服務?
不可以。管道是單向的,如果多個進程同時向管道中寫,那Golang的返回值就會錯亂。
可以多開幾個Golang進程實現,每個php進程對應一個Golang進程。
最後,上面都是瞎扯的。如果你了解管道、雙向管道,上面的解釋對你基本沒啥用。但如果你不了解管道,調試上面的代碼沒問題,但稍有修改就有可能掉坑裡。
❾ php網站中英文切換
多語言網站解決方案 php
前言:
多語言網站開發,重點的還是在解決語言之間的問題。
那如何解決這個問題呢?大概就分三步走:
1.頁面多語言
2.資料庫多語言
3.用戶訪問語言統一
1.頁面多語言
需要考慮的問題:
A.用戶登陸時候,自動識別字元,調用不同的語言包?
B.用戶切換不同語言時候,調用不同的語言包?
C.增加多語言後的目錄結構?
頁面多語言也就是外觀的多語言化,這里可以採用靜態的語言包的方式。
設計時候就應該包括language的目錄,針對不同語言有獨立的子目錄。
如英文language/en ,簡體中文language/gb,繁體中文language/b5 (可以擴展其他語言)
每個目錄下就包含了對每個頁面的語言版本。選擇語言版本時候就可以調用相應版本的語言包。
具體做法:
0.利用js語言,識別瀏覽器語言,在調用不同的語言包.
1.language/en/global.ln是針對英文版的全局語言包。
2.global.ln 內容為:
$title = "English webstie";
$charset = "UTF-8";
3.index.php調用:
<?php
require_once()
?>;
<html>;
<head>;
<title>;$title<title>;
<meta http-equiv="content-type" content="text/html;charset=$charset">;
</head>;
<body>;</body>;
</html>;
這樣通過擴展就可以實現頁面的多語言化.
2.資料庫多語言
這個考慮的問題:
A.後台錄入數據的多語言化?
B.用戶在不同版本下,提交的內容,如何保存?
C.提供三種語言包,還是提供英文和簡體,簡體通過轉化提供繁體?
資料庫多語言就是達到多語言在資料庫裡面的統一。就需要採用utf-8統一編碼。
無論什麼語言的文字,都統一使用utf-8來存放到資料庫裡面。採用表欄位來表識
屬於什麼語言版本的文字。
具體:
A.對於後台添加的問題:
1.後台添加時候,就需要多語言化的錄入。先建立一個以utf-8編碼的資料庫,錄入英文/簡體,簡體在通過轉化為繁體,
再以utf-8編碼方式存於資料庫中。
2.建立以utf-8為編碼的表結構,importlanguage標識屬於什麼語言版本
但在某個版本下,就搜索屬於這個版本的文字來顯示。其他文字不顯示。
DROP TABLE IF EXISTS `zz_importer`;
CREATE TABLE IF NOT EXISTS `zz_importer` (
`importID` int(11) NOT NULL auto_increment,
`importTime` date NOT NULL default '0000-00-00',
`improtfile` varchar(100) NOT NULL default '',
`importlanguage` varchar(100) NOT NULL default ''
PRIMARY KEY (`importID`)
) ENGINE=MyISAM DEFAULT CHARSET=uft-8;
3.簡體轉化的繁體。
利用php的iconv.此過程對於linux/unix有效,對於windows無效。
iconv("GB2312","BIG5",$text);
4.因為,charset = "utf-8",數據就都是以utf-8編碼方式存在,
添加數據時候,要分別用en/gb/big5來標識語言版本.
INSERT INTO `zz_importer` VALUES (,'', '', 'en');
INSERT INTO `zz_importer` VALUES (,'', '', 'gb');
INSERT INTO `zz_importer` VALUES (,'', '', 'big5');
B.對於用戶添加的問題:
1.假設下簡體中文下.用戶因為頁面頭為UTF-8.則用戶瀏覽器會以utf-8編碼
方式瀏覽頁面。
2.添加的資料庫本身以utf-8方式存在。
3.添加數據時候,要分別用gb來標識語言版本
INSERT INTO `zz_importer` VALUES (,'', '', 'gb');
C.對於簡體和繁體是單獨提供還是轉化問題
單獨提供 - 比較符合多語言的標准,靈活性大,對ISP沒有特別的要求。
轉化提供 - 提交速度會受影響,同時要ISP提供iconv的函數支持。
3.用戶訪問語言統一
A.假設用戶簡體中文版時候:
<meta http-equiv="content-type" content="text/html;charset=UTF-8">;
所有語言版本都是這樣。
B.調用language/gb的語言包。
C.搜索資料庫有語言欄位為gb的數據,並顯示
D.當用戶提交信息,參照上面資料庫多語言的B問題。
❿ 如何將php裡面的數組內容進行分頁顯示出來
1、前言
分頁顯示是一種非常常見的瀏覽和顯示大量數據的方法,屬於web編程中最常處理的事件之一。對於web編程的老手來說,編寫這種代碼實在是和呼吸一樣自然,但是對於初學者來說,常常對這個問題摸不著頭緒,因此特地撰寫此文對這個問題進行詳細的講解,力求讓看完這篇文章的朋友在看完以後對於分頁顯示的原理和實現方法有所了解。本文適合初學者閱讀,所有示例代碼均使用php編寫。
2、原理
所謂分頁顯示,也就是將資料庫中的結果集人為的分成一段一段的來顯示,這里需要兩個初始的參數:
每頁多少條記錄($PageSize)?
當前是第幾頁($CurrentPageID)?
現在只要再給我一個結果集,我就可以顯示某段特定的結果出來。
至於其他的參數,比如:上一頁($PreviousPageID)、下一頁($NextPageID)、總頁數($numPages)等等,都可以根據前邊這幾個東西得到。
以mysql資料庫為例,如果要從表內截取某段內容,sql語句可以用:select * from table limit offset, rows。看看下面一組sql語句,嘗試一下發現其中的規率。
前10條記錄:select * from table limit 0,10
第11至20條記錄:select * from table limit 10,10
第21至30條記錄:select * from table limit 20,10
……
這一組sql語句其實就是當$PageSize=10的時候取表內每一頁數據的sql語句,我們可以總結出這樣一個模板:
select * from table limit ($CurrentPageID - 1) * $PageSize, $PageSize
拿這個模板代入對應的值和上邊那一組sql語句對照一下看看是不是那麼回事。搞定了最重要的如何獲取數據的問題以後,剩下的就僅僅是傳遞參數,構造合適的sql語句然後使用php從資料庫內獲取數據並顯示了。以下我將用具體代碼加以說明。
3、簡單代碼
請詳細閱讀以下代碼,自己調試運行一次,最好把它修改一次,加上自己的功能,比如搜索等等。
<?php
// 建立資料庫連接
$link = mysql_connect("localhost", "mysql_user", "mysql_password")
or die("Could not connect: " . mysql_error());
// 獲取當前頁數
if( isset($_GET['page']) ){
$page = intval( $_GET['page'] );
}
else{
$page = 1;
}
// 每頁數量
$PageSize = 10;
// 獲取總數據量
$sql = "select count(*) as amount from table";
$result = mysql_query($sql);
$row = mysql_fetch_row($result);
$amount = $row['amount'];
// 記算總共有多少頁
if( $amount ){
if( $amount < $page_size ) //如果總數據量小於$PageSize,那麼只有一頁
if( $amount % $page_size ){ //取總數據量除以每頁數的余數
$page_count = (int)($amount / $page_size) + 1; //如果有餘數,則頁數等於總數據量除以每頁數的結果取整再加一
}else{
$page_count = $amount / $page_size; //如果沒有餘數,則頁數等於總數據量除以每頁數的結果
}
}
else{
$page_count = 0;
}
// 翻頁鏈接
$page_string = '';
if( $page == 1 ){
$page_string .= '第一頁|上一頁|';
}
else{
$page_string .= '<a href="/?page=1>";第一頁</a>|<a href="/?page='."($page-1).'>上一頁</a>|';
}
if( ($page == $page_count) || ($page_count == 0) ){
$page_string .= '下一頁|尾頁';
}
else{
$page_string .= '<a href="/?page='."($page+1).'>下一頁</a>|<a href="/?page='."$page_count.'>尾頁</a>';
}
// 獲取數據,以二維數組格式返回結果
if( $amount ){
$sql = "select * from table order by id desc limit ". ($page-1)*$page_size .", $page_size";
$result = mysql_query($sql);
while ( $row = mysql_fetch_row($result) ){
$rowset[] = $row;
}
}else{
$rowset = array();
}
// 沒有包含顯示結果的代碼,那不在討論范圍,只要用foreach就可以很簡單的用得到的二維數組來顯示結果
?>
4、OO風格代碼
以下代碼中的資料庫連接是使用的pear db類進行處理
<?php
// FileName: Pager.class.php
// 分頁類,這個類僅僅用於處理數據結構,不負責處理顯示的工作
Class Pager
{
var $PageSize; //每頁的數量
var $CurrentPageID; //當前的頁數
var $NextPageID; //下一頁
var $PreviousPageID; //上一頁
var $numPages; //總頁數
var $numItems; //總記錄數
var $isFirstPage; //是否第一頁
var $isLastPage; //是否最後一頁
var $sql; //sql查詢語句
function Pager($option)
{
global $db;
$this->_setOptions($option);
// 總條數
if ( !isset($this->numItems) )
{
$res = $db->query($this->sql);
$this->numItems = $res->numRows();
}
// 總頁數
if ( $this->numItems > 0 )
{
if ( $this->numItems < $this->PageSize )
if ( $this->numItems % $this->PageSize )
{
$this->numPages= (int)($this->numItems / $this->PageSize) + 1;
}
else
{
$this->numPages = $this->numItems / $this->PageSize;
}
}
else
{
$this->numPages = 0;
}
switch ( $this->CurrentPageID )
{
case $this->numPages == 1:
$this->isFirstPage = true;
$this->isLastPage = true;
break;
case 1:
$this->isFirstPage = true;
$this->isLastPage = false;
break;
case $this->numPages:
$this->isFirstPage = false;
$this->isLastPage = true;
break;
default:
$this->isFirstPage = false;
$this->isLastPage = false;
}
if ( $this->numPages > 1 )
{
if ( !$this->isLastPage )
if ( !$this->isFirstPage )
}
return true;
}
/***
*
* 返回結果集的資料庫連接
* 在結果集比較大的時候可以直接使用這個方法獲得資料庫連接,然後在類之外遍歷,這樣開銷較小
* 如果結果集不是很大,可以直接使用getPageData的方式獲取二維數組格式的結果
* getPageData方法也是調用本方法來獲取結果的
*
***/
function getDataLink()
{
if ( $this->numItems )
{
global $db;
$PageID = $this->CurrentPageID;
$from = ($PageID - 1)*$this->PageSize;
$count = $this->PageSize;
$link = $db->limitQuery($this->sql, $from, $count); //使用Pear DB::limitQuery方法保證資料庫兼容性
return $link;
}
else
{
return false;
}
}
/***
*
* 以二維數組的格式返回結果集
*
***/
function getPageData()
{
if ( $this->numItems )
{
if ( $res = $this->getDataLink() )
{
if ( $res->numRows() )
{
while ( $row = $res->fetchRow() )
{
$result[] = $row;
}
}
else
{
$result = array();
}
return $result;
}
else
{
return false;
}
}
else
{
return false;
}
}
function _setOptions($option)
{
$allow_options = array(
'PageSize',
'CurrentPageID',
'sql',
'numItems'
);
foreach ( $option as $key => $value )
{
if ( in_array($key, $allow_options) && ($value != null) )
{
$this->$key = $value;
}
}
return true;
}
}
?>
<?php
// FileName: test_pager.php
// 這是一段簡單的示例代碼,前邊省略了使用pear db類建立資料庫連接的代碼
require "Pager.class.php";
if ( isset($_GET['page']) )
{
$page = (int)$_GET['page'];
}
else
{
$page = 1;
}
$sql = "select * from table order by id";
$pager_option = array(
"sql" => $sql,
"PageSize" => 10,
"CurrentPageID" => $page
);
if ( isset($_GET['numItems']) )
{
$pager_option['numItems'] = (int)$_GET['numItems'];
}
$pager = @new Pager($pager_option);
$data = $pager->getPageData();
if ( $pager->isFirstPage )
{
$turnover = "首頁|上一頁|";
}
else
{
$turnover = "<a href='?page=1&numItems=".$pager->numItems."'>首頁</a>|<a href="/?page=".$pager->PreviousPageID."&numItems=".$pager->numItems."'>上一頁</a>|";
}
if ( $pager->isLastPage )
{
$turnover .= "下一頁|尾頁";
}
else
{
$turnover .= "<a href="/?page=".$pager->NextPageID."&numItems=".$pager->numItems."'>下一頁</a>|<a href="/?page=".$pager->numPages."&numItems=".$pager->numItems."'>尾頁</a>";
}
?>
需要說明的地方有兩個:
這個類僅僅處理數據,並不負責處理顯示,因為我覺得將數據的處理和結果的顯示都放到一個類里邊實在是有些勉強。顯示的時候情況和要求多變,不如自己根據類給出的結果處理,更好的方法是根據這個Pager類繼承一個自己的子類來顯示不同的分頁,比如顯示用戶分頁列表可以:
<?php
Class MemberPager extends Pager
{
function showMemberList()
{
global $db;
$data = $this->getPageData();
// 顯示結果的代碼
// ......
}
}
/// 調用
if ( isset($_GET['page']) )
{
$page = (int)$_GET['page'];
}
else
{
$page = 1;
}
$sql = "select * from members order by id";
$pager_option = array(
"sql" => $sql,
"PageSize" => 10,
"CurrentPageID" => $page
);
if ( isset($_GET['numItems']) )
{
$pager_option['numItems'] = (int)$_GET['numItems'];
}
$pager = @new MemberPager($pager_option);
$pager->showMemberList();
?>
第二個需要說明的地方就是不同資料庫的兼容性,在不同的資料庫里截獲一段結果的寫法是不一樣的。
mysql: select * from table limit offset, rows
pgsql: select * from table limit m offset n
......
所以要在類里邊獲取結果的時候需要使用pear db類的limitQuery方法。
ok,寫完收功,希望花時間看完這些文字的你不覺得是浪費了時間。
回答者
另外,虛機團上產品團購,超級便宜