初学Phreeze

换了份工作,换了个框架,那就学学吧。。

我从网站上下载了phreeze-master,这是一个成功的案例,我自己写了一个案例,同样是成功的,现在我来说一下需要注意的地方。

Phreeze 同样是单一入口的文件,他和其它框架首先特别明显的不同点是他的三个文件:‘_app_config.php’,'_global_config.php','_machine_config.php',这三个文件是整个项目的配置文件,这三个文件的加载顺序是:

include_once("_global_config.php");//defines a singleton the setting
include_once("_app_config.php");//the php include path
include_once("_machine_config.php");//contains the setting the pertain to a specific server environment

_mechine_config.php
 1 <?php
 2 /**
 3  * @package Adserv
 4  *
 5  * MACHINE-SPECIFIC CONFIGURATION SETTINGS
 6  *
 7  * The configuration settings in this file can be changed to suit the
 8  * machine on which the app is running (ex. local, staging or production).
 9  *
10  * This file should not be added to version control, rather a template
11  * file should be added instead and then copied for each install
12  */
13 
14 require_once 'verysimple/Phreeze/ConnectionSetting.php';
15 require_once("verysimple/HTTP/RequestUtil.php");
16 
17 /**
18  * Normally DB connection info would go here, but phreeze builder doesn't actually
19  * have any back-end schema
20  */
21 GlobalConfig::$CONNECTION_SETTING = new ConnectionSetting();
22 GlobalConfig::$CONNECTION_SETTING->ConnectionString = "";
23 GlobalConfig::$CONNECTION_SETTING->DBName = "";
24 GlobalConfig::$CONNECTION_SETTING->Username = "";
25 GlobalConfig::$CONNECTION_SETTING->Password = "";
26 
27 /** the root url of the application with trailing slash, for example http://localhost/adserv/ */
28 GlobalConfig::$ROOT_URL = RequestUtil::GetServerRootUrl() . 'phreeze/builder/';
29 
30 /** timezone */
31 // date_default_timezone_set("UTC");
32 
33 /** functions for php 5.2 compatibility */
34 if (!function_exists('lcfirst')) {
35     function lcfirst($string) {
36         return substr_replace($string, strtolower(substr($string, 0, 1)), 0, 1);
37     }
38 }
39 
40 /** level 2 cache */
41 
42 /** additional machine-specific settings */
43 
44 ?>
_app_config.php
 1 <?php
 2 
 3 GlobalConfig::$APP_ROOT=realpath('./');
 4 
 5 set_include_path(
 6     GlobalConfig::$APP_ROOT.'/libs/'.PATH_SEPARATOR.
 7     GlobalConfig::$APP_ROOT.'/../libs'.PATH_SEPARATOR.
 8     get_include_path()
 9 );
10 
11 require_once 'verysimple/Phreeze/SavantRenderEngine.php';
12 GlobalConfig::$TEMPLATE_ENGINE = 'SmartyRenderEngine';
13 GlobalConfig::$TEMPLATE_PATH = GlobalConfig::$APP_ROOT . '/templates/';
14 GlobalConfig::$TEMPLATE_CACHE_PATH = '';
15 
16 
17 GlobalConfig::$ROUTE_MAP = array(
18 
19     'GET:' => array('route' => 'Default.Home'),
20     'POST:generate' => array('route' => 'Generator.Generate'),
21     'POST:hello' => array('route' => 'Hello.Say')
22 );
23 
24 ?>
_global_config.php
  1 <?php
  2 /**
  3  * @package Adserv
  4  *
  5  * GLOBAL CONFIGURATION
  6  *
  7  * This file defines a singleton class that is used for dependency injection
  8  * into the framework dispatcher.
  9  *
 10  * For the most part the settings here shouldn't be changed.  The static
 11  * properties can be changed in either _app_config.php or _machine_config.php
 12  * depending on whether the setting is application-wide or machine-specific
 13  */
 14 
 15 /**
 16  * GlobalConfig is a singleton containing the global variables.
 17  * In general settings should not be changed in this file and should instead
 18  * be made in either _app_config.php or _machine_config.php
 19  *
 20  * For unit testing this object can be swapped out with another object entirely
 21  * to allow for mock data, mockput, etc as needed
 22  *
 23  * @package Adserv
 24  * @author ClassBuilder
 25  */
 26 class GlobalConfig
 27 {
 28     /** @var set to true to send debug info to the browser */
 29     public static $DEBUG_MODE = false;
 30 
 31     /** @var default action is the controller.method fired when no route is specified */
 32     public static $DEFAULT_ACTION = "Default.Home";
 33 
 34     /** @var routemap is an array of patterns and routes */
 35     public static $ROUTE_MAP;
 36 
 37     /** @var specify the template render engine (Smarty, Savant, PHP) */
 38     public static $TEMPLATE_ENGINE = 'SmartyRenderEngine';
 39 
 40     /** @var template path is the physical location of view template files */
 41     public static $TEMPLATE_PATH;
 42 
 43     /** @var template cache path is the physical location where templates can be cached */
 44     public static $TEMPLATE_CACHE_PATH;
 45 
 46     /** @var app root is the root directory of the application */
 47     public static $APP_ROOT;
 48 
 49     /** @var root url of the application */
 50     public static $ROOT_URL;
 51 
 52     /** @var ConnectionSetting object containign settings for the DB connection **/
 53     public static $CONNECTION_SETTING;
 54 
 55     /** @var ICache (optional) object for level 2 caching (for example memcached) **/
 56     public static $LEVEL_2_CACHE;
 57 
 58     /** @var string if level 2 cache is specified, a temp path for writing files */
 59     public static $LEVEL_2_CACHE_TEMP_PATH;
 60 
 61     /** @var int if level 2 cache is specified, the timeout in seconds*/
 62     public static $LEVEL_2_CACHE_TIMEOUT = 15;
 63 
 64     private static $INSTANCE;
 65     private static $IS_INITIALIZED = false;
 66 
 67     private $context;
 68     private $router;
 69     private $phreezer;
 70     private $render_engine;
 71 
 72     /** prevents external construction */
 73     private function __construct(){}
 74 
 75     /** prevents external cloning */
 76     private function __clone() {}
 77 
 78     /**
 79      * Initialize the GlobalConfig object
 80      */
 81     static function Init()
 82     {
 83         require_once 'verysimple/Phreeze/Controller.php';
 84         require_once 'verysimple/HTTP/RequestUtil.php';
 85 
 86         if (!self::$IS_INITIALIZED)
 87         {
 88             RequestUtil::NormalizeUrlRewrite();
 89 
 90             Controller::$SmartyViewPrefix = '';
 91             Controller::$DefaultRedirectMode = 'header';
 92 
 93             self::$IS_INITIALIZED = true;
 94         }
 95 
 96     }
 97 
 98     /**
 99      * Returns an instance of the GlobalConfig singleton
100      * @return GlobalConfig
101      */
102     static function GetInstance()
103     {
104         if (!self::$IS_INITIALIZED) self::Init();
105 
106         if (!self::$INSTANCE instanceof self) self::$INSTANCE = new self;
107 
108         return self::$INSTANCE;
109     }
110 
111     /**
112      * Returns the context, used for storing session information
113      * @return Context
114      */
115     function GetContext()
116     {
117         if ($this->context == null)
118         {
119         }
120         return $this->context;
121 
122     }
123 
124     /**
125      * Returns a URL Writer used to parse/generate URLs
126      * @return UrlWriter
127      */
128     function GetRouter()
129     {
130         if ($this->router == null)
131         {
132             require_once("verysimple/Phreeze/GenericRouter.php");
133             $this->router = new GenericRouter(self::$ROOT_URL,self::GetDefaultAction(),self::$ROUTE_MAP);
134         }
135         return $this->router;
136     }
137 
138 
139     /**
140      * Returns the requested action requested by the user
141     * @return string
142     */
143     function GetAction()
144     {
145         list($controller,$method) = $this->GetRouter()->GetRoute();
146         return $controller.'.'.$method;
147     }
148 
149     /**
150      * Returns the default action if none is specified by the user
151      * @return string
152      */
153     function GetDefaultAction()
154     {
155         return self::$DEFAULT_ACTION;
156     }
157 
158     /**
159      * Returns the Phreezer persistance layer
160      * @return Phreezer
161      */
162     function GetPhreezer()
163     {
164         if ($this->phreezer == null)
165         {
166             if (self::$DEBUG_MODE)
167             {
168                 require_once("verysimple/Phreeze/ObserveToSmarty.php");
169                 $observer = new ObserveToSmarty($this->GetRenderEngine());
170                 $this->phreezer = new Phreezer(self::$CONNECTION_SETTING, $observer);
171             }
172             else
173             {
174                 $this->phreezer = new Phreezer(self::$CONNECTION_SETTING);
175             }
176 
177             if (self::$LEVEL_2_CACHE)
178             {
179                 $this->phreezer->SetLevel2CacheProvider( self::$LEVEL_2_CACHE, SELF::LEVEL_2_CACHE_TEMP_PATH );
180                 $this->phreezer->ValueCacheTimeout = self::$LEVEL_2_CACHE_TIMEOUT;
181             }
182         }
183 
184         return $this->phreezer;
185     }
186 
187     /**
188      * @return IRenderEngine
189      */
190     function GetRenderEngine()
191     {
192         if ($this->render_engine == null)
193         {
194             $engine_class = self::$TEMPLATE_ENGINE;
195             if (!class_exists($engine_class))
196             {
197                 require_once 'verysimple/Phreeze/'. $engine_class  . '.php';
198             }
199             $this->render_engine = new $engine_class(self::$TEMPLATE_PATH,self::$TEMPLATE_CACHE_PATH);
200             $this->render_engine->assign("ROOT_URL",self::$ROOT_URL);
201             $this->render_engine->assign("PHREEZE_VERSION",Phreezer::$Version);
202             $this->render_engine->assign("PHREEZE_PHAR",Phreezer::PharPath());
203         }
204 
205         return $this->render_engine;
206     }
207 
208 }
209 
210 ?>

这是三个文件,里面的内容可以根据自己的修改

index.php
 1 <?php
 2 /** @package    Phreeze Builder */
 3 
 4 /* GlobalConfig object contains all configuration information for the app */
 5  include_once("_global_config.php");
 6  include_once("_app_config.php");
 7  include_once("_machine_config.php");
 8 
 9 /* require framework libs */
10 require_once("verysimple/Phreeze/Dispatcher.php");
11 
12 // the global config is used for all dependency injection
13 $gc = GlobalConfig::GetInstance();
14 
15 try
16 {
17     Dispatcher::Dispatch(
18         $gc->GetPhreezer(),
19         $gc->GetRenderEngine(),
20         '',
21         $gc->GetContext(),
22         $gc->GetRouter()
23     );
24 }
25 catch (exception $ex)
26 {
27     $gc->GetRenderEngine()->assign("message",$ex->getMessage());
28     $gc->GetRenderEngine()->assign("stacktrace",$ex->getTraceAsString());
29     $gc->GetRenderEngine()->assign("code",$ex->getCode());
30 
31     try
32     {
33         $gc->GetRenderEngine()->display("DefaultErrorFatal.tpl");
34     }
35     catch (Exception $ex2)
36     {
37         // this means there is an error with the template, in which case we can't display it nicely
38         echo "<style>* { font-family: verdana, arial, helvetica, sans-serif; }</style>\n";
39         echo "<h1>Fatal Error:</h1>\n";
40         echo '<h3>' . htmlentities($ex->getMessage()) . "</h3>\n";
41         echo "<h4>Original Stack Trace:</h4>\n";
42         echo '<textarea wrap="off" style="height: 200px; width: 100%;">' . htmlentities($ex->getTraceAsString()) . '</textarea>';
43         echo "<h4>In addition to the above error, the default error template could not be displayed:</h4>\n";
44         echo '<textarea wrap="off" style="height: 200px; width: 100%;">' . htmlentities($ex2->getMessage()) . "\n\n" . htmlentities($ex2->getTraceAsString()) . '</textarea>';
45     }
46 
47 }
48 
49 ?>

这是我的入口文件。

注意:

  1.他的Controller文件,存放在libs/Controller下面,其文件的命名格式和zend framework一样,其实在他的verysimple/phreeze/Dispatcher.php文件里面的Dispatch方法中我们可以看到,当libs和libs/Controller下面找不到控制器的时候,他会去整个路径下面找,

Dispatcher.php/Dispatch
 1 static function Dispatch($phreezer,$renderEngine,$action='',$context=null,$router=null)
 2     {
 3         if ($router == null)
 4         {
 5             require_once('GenericRouter.php');
 6             $router = new GenericRouter();
 7         }
 8 
 9         list($controller_param,$method_param) = $router->GetRoute( $action );
10 
11         // normalize the input
12         $controller_class = $controller_param."Controller";
13         $controller_file = "Controller/" . $controller_param . "Controller.php";
14 
15         // look for the file in the expected places, hault if not found
16         if ( !(file_exists($controller_file) || file_exists("libs/".$controller_file)) )
17         {
18             // go to plan be, search the include path for the controller
19             $paths = explode(PATH_SEPARATOR,get_include_path());
20             $found = false;
21             foreach ($paths as $path)
22             {
23                 if (file_exists($path ."/".$controller_file))
24                 {
25                     $found = true;
26                     break;
27                 }
28             }
29 
30             if (!$found) throw new Exception("File ~/libs/".$controller_file." was not found in include path");
31         }
32 
33         // convert any php errors into an exception
34         if (self::$IGNORE_DEPRECATED)
35         {
36             ExceptionThrower::Start();
37         }
38         else
39         {
40             ExceptionThrower::Start(E_ALL);
41             ExceptionThrower::$IGNORE_DEPRECATED = false;
42         }
43 
44         // we should be fairly certain the file exists at this point
45         include_once($controller_file);
46 
47         // we found the file but the expected class doesn't appear to be defined
48         if (!class_exists($controller_class))
49         {
50             throw new Exception("Controller file was found, but class '".$controller_class."' is not defined");
51         }
52 
53 
54         // create an instance of the controller class
55         $controller = new $controller_class($phreezer,$renderEngine,$context,$router);
56         
57         // we have a valid instance, just verify there is a matching method
58         if (!is_callable(array($controller, $method_param)))
59         {
60             throw new Exception("'".$controller_class.".".$method_param."' is not a valid action");
61         }
62 
63         // do not call the requested method/route if the controller request has been cancelled
64         if (!$controller->IsTerminated())
65         {
66             // file, class and method all are ok, go ahead and call it
67             call_user_func(array(&$controller, $method_param));
68         }
69 
70         // reset error handling back to whatever it was
71         //restore_exception_handler();
72         ExceptionThrower::Stop();
73 
74         return true;
75     }

2.它的模板的命名为你的指定名称,或者是你的控制器名称+方法名称.tpl

3.在zendFramework 里面我们的方法名称是小写的驼峰标记,这个phreeze里面是大写的驼峰标记

4.他的文件上传在Http/RequestUrl.php/getFileUpload ,返回对象为FileUpload对象,

5,目前我就知道有两个渲染引擎SmartyRenderEngine.php,SavantRenderEngine.php,这个配置项在_global_config.php里面,

public static $TEMPLATE_ENGINE = 'SmartyRenderEngine';

6。我们项目99%会合数据库打交道,_machine_config.php,里面就配置了连接数据库的选项,

LinkDb
1 /** database connection settings */
2 GlobalConfig::$CONNECTION_SETTING = new ConnectionSetting();
3 GlobalConfig::$CONNECTION_SETTING->ConnectionString = "localhost:3306";
4 GlobalConfig::$CONNECTION_SETTING->DBName = "test";
5 GlobalConfig::$CONNECTION_SETTING->Username = "root";
6 GlobalConfig::$CONNECTION_SETTING->Password = "root";
7 GlobalConfig::$CONNECTION_SETTING->Type = "MySQL";
8 GlobalConfig::$CONNECTION_SETTING->Charset = "utf8";

7.当我们的controller,需要model时,他的Controller名称就是model名称,并且他的每一个model,都会在Model/DAO里面有个一样名字+DAO的文件

class test extends testDAO{.......}

8.我们再写zendframework的时候每一个控制器都会继承它自身d的Controller.php,我以前再用zf的时候就经常自己在另外写一个文件继承Controller文件,然后所有的Controller继承我自己写的文件,这种好处在Phreeze里面也得到了体现,因为Phreeze的Controller是抽象类,它里面有init这个抽象方法,如果我们让我们的每一个Controller都去继承它自身的,我们也有可能在每个controller里面都用到好几个相同的方法,这样就会浪费我们的时间,这是我为什么在zf里面自己写一个controller的原因(自己的思路,不代表官方)

9,我们的index.php是如何指向类和方法的呢,这是在我们de _global_config.php里面设置的public static $DEFAULT_ACTION = "Default.Home";_app_config.php里面的

 'GET:' => array('route' => 'Default.Home'),也要修改,_global_config文件的貌似无效果,但是之修改_app_config.php的那个有效果

10,在_app_config.php里面我们可以设置:

1 GlobalConfig::$ROUTE_MAP = array(
2 
3     'GET:' => array('route' => 'Default.Home'),
4     'POST:generate' => array('route' => 'Generator.Generate'),
5     'POST:hello' => array('route' => 'Hello.Say')
6 );

这个设置的好处是,我们只需要填写很简单的内容他就可以找到我们想要的位置,而且当作为参数的时候,我们可以按照下面这个这么写:


1 GlobalConfig::$ROUTE_MAP = array(
2  
3     'GET:api/sales/customer/(:num)' => array(
4         'route' => 'Customer.View', 
5         'params' => array('customerId' => 3)
6     )
7     
8 );
http://localhost/api/sales/customer/25 would be split into 4 parts:

0= api
1= sales
2= customer
3=25

 

13,他的DB函数verySimple/DB/reflection/文件夹下面有很多的函数,

DbConnection.php/connect
 1 function Connect()
 2     {
 3         $this->handler->Log(DBH_LOG_INFO, "Opening Connection...");
 4         if ($this->dbopen)
 5         {
 6             $this->handler->Log(DBH_LOG_WARNING, "Connection Already Open");
 7         }
 8         else
 9         {
10             if ( !$this->dbconn = mysql_connect($this->Host . ":" . $this->Port, $this->Username, $this->Password) )
11             {
12                 $this->handler->Crash(DatabaseException::$CONNECTION_ERROR,"Error connecting to database: " . mysql_error());
13             }
14 
15             if (!mysql_select_db($this->DBName, $this->dbconn))
16             {
17                 $this->handler->Crash(DatabaseException::$CONNECTION_ERROR,"Unable to select database " . $this->DBName);
18             }
19 
20             $this->handler->Log(DBH_LOG_INFO, "Connection Open");
21             $this->dbopen = true;
22         }
23     }

verysimple/DB/DataDriver/MYSQL.php里面,看着段代码大家应该很容易理解query和execute的区别:

dataDriver/mysql.php
 1     function Query($connection,$sql) 
 2     {
 3         if ( !$rs = @mysql_query($sql, $connection) )
 4         {
 5             throw new DatabaseException(mysql_error(),DatabaseException::$ERROR_IN_QUERY);
 6         }
 7         
 8         return $rs;
 9     }
10 
11     /**
12      * @inheritdocs
13      */
14     function Execute($connection,$sql) 
15     {
16         if ( !$result = @mysql_query($sql, $connection) )
17         {
18             throw new DatabaseException(mysql_error(),DatabaseException::$ERROR_IN_QUERY);
19         }
20         
21         return mysql_affected_rows($connection);
22     }

对于这个文件里面我现在有个地方不能理解:

1 function Fetch($connection,$rs) 
2     {
3         return mysql_fetch_assoc($rs);
4     }
他的方法的参数里面,根本不用$connection ,可是它写了

 

 

12,它可以渲染很多格式的代码,这个貌似不错,可是没用呢还

还有很多函数,建议大家看代码的时候直接看源码,那么着用起来比较方便,理解的也比较快,

DB应用:

第一种方法:
 $obj=new DataDriverMySQL();
$sql='select * from ptest where id=20';
$connection=$obj->Open('localhost:3306','PhreezeTest','root','root','utf8');
$rs=$obj->Query($connection,$sql);
$arrName2=$obj->Fetch($connection,$rs);
echo '<pre>';
print_r($arrName2);
echo '</pre>';
结果:
Array
(
    [id] => 20
    [name] => G
    [time] => 2013-02-21 15:19:48
)

第二种方法:
                $cstring = $this->GetConnectionString();
        $handler = new DBEventHandler();
        $connection = new DBConnection($cstring, $handler);
        $server = new DBServer($connection);
        $sql='select * from ptest where id=25';
        $rs=$connection->Select($sql);
        $arrName=$connection->Next($rs);
        echo '<pre>';
        print_r($arrName);
        echo '</pre>';
        Array
        (
                [id] => 25
                [name] => Zc
                [time] => 2013-02-21 15:19:48
        )
说明:数据是我批量插入的,你可能会说时间为什么一样,我想说时间差太小,        

ps:我目前还没有找到他和zf一样的fetchAll功能的方法;

我不能肯定这里面没有错误,这也仅仅是我刚开始所了解到的表面层次的东西,如果您正好了解这个Phreeze框架,那么请您批评指教,谢谢!

 

posted @ 2013-02-21 14:53  尹少爷  阅读(417)  评论(0编辑  收藏  举报