热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SinaAppEngine(SAE)教程(11)Yaf使用

Yaf参考资料Yaf(YetAnotherFramework)用户手册想在SAE使用Yaf?无需申请,sae环境已经全面支持。Yaf实战下面是一个运行在SAE的Yaf的hellow

Yaf参考资料
  • Yaf(Yet Another Framework)用户手册

想在SAE使用Yaf?

无需申请,sae环境已经全面支持。

Yaf 实战

下面是一个运行在SAE的Yaf的hello world程序。

config.yaml

---
name: lazydemo
version: 3
...
handle:
    - rewrite: if(!is_dir() && !is_file() && path ~ "^(.*)$" ) goto "/index.php"

以上文件配置了Rewrite规则,把所有这个应用的请求, 都定向到上面提到的入口文件。

index.php

php
define("APP_PATH",  dirname(__FILE__));
$app  = new Yaf_Application(APP_PATH . "/conf/application.ini");
$app->run();

/conf/application.ini

[product]
application.directory=APP_PATH "/application/"

控制器文件:Index.php

php
class IndexController extends Yaf_Controller_Abstract {
   public function indexAction() {//默认Action
       $this->getView()->assign("content", "Hello World");
   }
}
?>

视图文件 index.phtml

<html>
 <head>
   <title>Hello Worldtitle>
 head>
 <body>
  php echo $content;?>
 body>
html>

文件目录请直接下载demo文件包查看,也可以点击http://yaf.laruence.com/manual/tutorial.firstpage.html 目录结构查看。效果见:http://3.lazydemo.sinaapp.com/demo 文件打包下载:
http://3.lazydemo.sinaapp.com/SAE_Yaf_helloworld_demo.zip

深化认识

天天都是helloworld自然不行,下面就进一步的深化。我们就先从数据库的连接开始,首先修改下/conf/application.ini的设置加上sae数据库的相关配置。文件如下:

[base]
database.master.host = 3.lazydemo.sinaapp.com
[product]
;支持直接写PHP中的已定义常量
application.directory=APP_PATH "/application/" 
;应用的配置
webhost                  = 3.lazydemo.sinaapp.com
database.adapter         = pdo_mysql
;主库
database.params.host.m   = SAE_MYSQL_HOST_M
;从库
database.params.host.s   = SAE_MYSQL_HOST_S
database.params.port     = SAE_MYSQL_PORT
database.params.username = SAE_MYSQL_USER
database.params.password = SAE_MYSQL_PASS
database.params.dbname   = SAE_MYSQL_DB

那我们怎么在程序中读出这个配置呢?这时候就需要用到yaf的Yaf_Config_Ini(参考文档)
我们可以做个实现,我们在默认的控制器中通过Yaf_Config_Ini来读取刚刚配置的数据库连接信息,控制器Index.php的代码改成如下:

php
class IndexController extends Yaf_Controller_Abstract {
   public function indexAction() {//默认Action
           //test get db connection info
           //获取当前web目录的绝对路径
           $br = ‘
; $basedir = $_SERVER[ ‘DOCUMENT_ROOT‘]; $conf_dir = $basedir.‘/conf/application.ini‘; $config = new Yaf_Config_Ini($conf_dir,‘product‘); echo $config->database->get("params")->host->m.$br; echo $config->database->get("params")->host->s.$br; echo $config->get("database")->params->dbname.$br; $this->getView()->assign("content", "Hello World"); } } ?>

此时访问http://3.lazydemo.sinaapp.com/ (ps可能你点击看不到了,因为我改成了其他的代码,你可以自己复制上面的代码实验)

w.rdc.sae.sina.com.cn
r.rdc.sae.sina.com.cn
app_lazydemo
Hello World

成功了!那么其他的一些配置文件都可以参考以上的方法实现。截止到以上操作的代码文件打包下载:http://3.lazydemo.sinaapp.com/SAE_Yaf_demo_step2.zip

Yaf的一大亮点:Yaf_Registry

Yaf_Registry, 对象注册表(或称对象仓库)是一个用于在整个应用空间(application space)内存储对象和值的容器. 通过把对象存储在其中,我们可以在整个项目的任何地方使用同一个对象.这种机制相当于一种全局存储. 我们可以通过Yaf_Registry类的静态方法来使用对象注册表. 另外,由于该类是一个数组对象,你可以使用数组形式来访问其中的类方法.

这就好比为我们实现了一个类似SAE的kv存取,但是这个存取会随着访问的结束而释放,不需要手工清空。下面我们也通过一个简单的例子来说明这几个函数:

  • Yaf_Registry::set
  • Yaf_Registry::get
  • Yaf_Registry::has
  • Yaf_Registry::del

为了测试我们改写Index.php代码如下:

 
php
class IndexController extends Yaf_Controller_Abstract {
   public function indexAction() {//默认Action
           //我们在这里注册,不放直接注册一个数组试试
           $value = array(‘name‘=>‘lazy‘,‘age‘=>‘21‘);
           $re = Yaf_Registry::set(‘config‘,$value);
           var_dump($re);
           $config = Yaf_Registry::get("config");
       var_dump($config);
       $this->getView()->assign("content", "This is index page");
   }
}
?>

访问可以得到结果

bool(true) array(2) { ["name"]=> string(4) "lazy" ["age"]=> string(2) "21" } This is index page

这个例子的demo源代码下载地址 http://3.lazydemo.sinaapp.com/SAE_Yaf_demo_step3.zip

关闭自动渲染,display函数实例

可能在有些时候,我们确实不想把页面的内容都刷到一固定的view中,例如你的控制器叫Test.php,那你的indexAction默认的自动渲染就是到views/test/index.phtml 文件里了,display函数可以允许我们改变渲染的视图文件,例如在Test控制器中,我们想把后端的数据刷到lazy.phtml中,我们可以将Test.php改写成:

php
class TestController extends Yaf_Controller_Abstract {
    public function init(){
           /* 首先关闭自动渲染 */
           Yaf_Dispatcher::getInstance()->disableView();
        }

   public function indexAction() {
       $this->initView();
       $this->display("lazy", array("content" => "this comes from test controller index action"));
       //注意第一个参数直接写lazy就行,写成lazy.phtml会出错
   }
}
?>

在views/test/下新建文件 lazy.phtml,文件的内容是

<html>
 <head>
   <title>Hello Worldtitle>
 head>
 <body>
  php echo $content;?>
 body>
html>

访问http://3.lazydemo.sinaapp.com/test就可以看到输出是:

this comes from test controller index action

本实例源代码下载地址:http://3.lazydemo.sinaapp.com/SAE_Yaf_demo_step4.zip

添加前端和数据库操作类

下面开始将对yaf做一些深度的添加树叶让他更好的在SAE上能给开发者快速的开发。首先我想添加一个类似于 Lazyphp那样的专门对SAE的数据库的封装函数,将其一样的在yaf中实现,类似的函数有get_line,get_var,run_sql等等,可以参考http://ftqq.com/lazyphp/ 下面的关于数据库的列表。

那么要实现这些个功能,我们就必须要借用Yaf提供的bootstrap对其完成初始化了。

我们首先在application下创建一个functions的文件夹,写入db.sae.function.php 文件,文件的内容是:

php

function db_read( $host = null , $port = null , $user = null , $password = null , $db_name = null )
{
        $db_key = MD5( ‘read-‘ . $host .‘-‘. $port .‘-‘. $user .‘-‘. $password .‘-‘. $db_name  );
        
        if( !isset( $GLOBALS[‘LP_‘.$db_key] ) )
        {
                $basedir = $_SERVER[ ‘DOCUMENT_ROOT‘];
        $conf_dir = $basedir.‘/conf/application.ini‘;
        $config = new Yaf_Config_Ini($conf_dir,‘product‘);              
                if( $host == null ) $host = $config->database->get("params")->host->s;
                if( $port == null ) $port = $config->database->get("params")->port;
                if( $user == null ) $user = $config->database->get("params")->username;
                if( $password == null ) $password = $config->database->get("params")->password;
                if( $db_name == null ) $db_name = $config->database->get("params")->dbname;
                
                if( !$GLOBALS[‘LP_‘.$db_key] = mysql_connect( $host.‘:‘.$port , $user , $password , true ) )
                {
                        //
                        echo ‘can\‘t connect to database‘;
                        return false;
                }
                else
                {
                        if( $db_name != ‘‘ )
                        {
                                if( !mysql_select_db( $db_name , $GLOBALS[‘LP_‘.$db_key] ) )
                                {
                                        echo ‘can\‘t select database ‘ . $db_name ;
                                        return false;
                                }
                        }
                }
                
                mysql_query( "SET NAMES ‘UTF8‘" , $GLOBALS[‘LP_‘.$db_key] );
        }
        
        return $GLOBALS[‘LP_‘.$db_key];
}


// db functions
function db( $host = null , $port = null , $user = null , $password = null , $db_name = null )
{
        $db_key = MD5( $host .‘-‘. $port .‘-‘. $user .‘-‘. $password .‘-‘. $db_name  );
        
        if( !isset( $GLOBALS[‘LP_‘.$db_key] ) )
        {
                $basedir = $_SERVER[ ‘DOCUMENT_ROOT‘];
        $conf_dir = $basedir.‘/conf/application.ini‘;
        $config = new Yaf_Config_Ini($conf_dir,‘product‘);              
                if( $host == null ) $host = $config->database->get("params")->host->m;
                if( $port == null ) $port = $config->database->get("params")->port;
                if( $user == null ) $user = $config->database->get("params")->username;
                if( $password == null ) $password = $config->database->get("params")->password;
                if( $db_name == null ) $db_name = $config->database->get("params")->dbname;
                                
                if( !$GLOBALS[‘LP_‘.$db_key] = mysql_connect( $host.‘:‘.$port , $user , $password , true ) )
                {
                        //
                        echo ‘can\‘t connect to database‘;
                        return false;
                }
                else
                {
                        if( $db_name != ‘‘ )
                        {
                                if( !mysql_select_db( $db_name , $GLOBALS[‘LP_‘.$db_key] ) )
                                {
                                        echo ‘can\‘t select database ‘ . $db_name ;
                                        return false;
                                }
                        }
                }
                
                mysql_query( "SET NAMES ‘UTF8‘" , $GLOBALS[‘LP_‘.$db_key] );
        }
        
        return $GLOBALS[‘LP_‘.$db_key];
}

function s( $str , $db = NULL )
{
        if( $db == NULL ) $db = db();
        return   mysql_real_escape_string( $str , $db )  ;
        
}

// $sql = "SELECT * FROM `user` WHERE `name` = ?s AND `id` = ?i LIMIT 1 "
function prepare( $sql , $array )
{
        
        foreach( $array as $k=>$v )
                $array[$k] = s($v );
        
        $reg = ‘/\?([is])/i‘;
        $sql = preg_replace_callback( $reg , ‘prepair_string‘ , $sql  );
        $count = count( $array );
        for( $i = 0 ; $i <$count; $i++ )
        {
                $str[] = ‘$array[‘ .$i . ‘]‘;   
        }
        
        $statement = ‘$sql = sprintf( $sql , ‘ . join( ‘,‘ , $str ) . ‘ );‘;
        eval( $statement );
        return $sql;
        
}

function prepair_string( $matches )
{
        if( $matches[1] == ‘s‘ ) return "‘%s‘";
        if( $matches[1] == ‘i‘ ) return "‘%d‘"; 
}


function get_data( $sql , $db = NULL )
{
        if( $db == NULL ) $db = db_read();
        
        $GLOBALS[‘LP_LAST_SQL‘] = $sql;
        $data = Array();
        $i = 0;
        $result = mysql_query( $sql ,$db );
        
        if( mysql_errno() != 0 )
                echo mysql_error() .‘ ‘ . $sql;
        
        while( $Array = mysql_fetch_array($result, MYSQL_ASSOC ) )
        {
                $data[$i++] = $Array;
        }
        
        if( mysql_errno() != 0 )
                echo mysql_error() .‘ ‘ . $sql;
        
        mysql_free_result($result); 

        if( count( $data ) > 0 )
                return $data;
        else
                return false;
}

function get_line( $sql , $db = NULL )
{
        $data = get_data( $sql , $db  );
        return @reset($data);
}

function get_var( $sql , $db = NULL )
{
        $data = get_line( $sql , $db );
        return $data[ @reset(@array_keys( $data )) ];
}

function last_id( $db = NULL )
{
        if( $db == NULL ) $db = db();
        return get_var( "SELECT LAST_INSERT_ID() " , $db );
}

function run_sql( $sql , $db = NULL )
{
        if( $db == NULL ) $db = db();
        $GLOBALS[‘LP_LAST_SQL‘] = $sql;
        return mysql_query( $sql , $db );
}

function db_errno( $db = NULL )
{
        if( $db == NULL ) $db = db();
        return mysql_errno( $db );
}


function db_error( $db = NULL )
{
        if( $db == NULL ) $db = db();
        return mysql_error( $db );
}

function last_error()
{
        if( isset( $GLOBALS[‘LP_DB_LAST_ERROR‘] ) )
        return $GLOBALS[‘LP_DB_LAST_ERROR‘];
}

function close_db( $db = NULL )
{
        if( $db == NULL )
                $db = $GLOBALS[‘LP_DB‘];
                
        unset( $GLOBALS[‘LP_DB‘] );
        mysql_close( $db );
}

?>

这个文件基本和lazyphp中的一样,但是数据库的配置信息那里我做了一点修改,不再是require得到,而是采用

$basedir = $_SERVER[ ‘DOCUMENT_ROOT‘];
$conf_dir = $basedir.‘/conf/application.ini‘;
$config = new Yaf_Config_Ini($conf_dir,‘product‘);              
if( $host == null ) $host = $config->database->get("params")->host->m;
if( $port == null ) $port = $config->database->get("params")->port;
if( $user == null ) $user = $config->database->get("params")->username;
if( $password == null ) $password = $config->database->get("params")->password;
if( $db_name == null ) $db_name = $config->database->get("params")->dbname;

读取/conf/application.ini的配置文件得到,这个用户在上面已经介绍了。不再赘述,在实现后我们就需要在bootstrap中初始化引用这些函数,注意,Bootstrap.php的文件必须在application的根目录下。看我写的Bootstrap.php代码:

php

/**
 * 所有在Bootstrap类中, 以_init开头的方法, 都会被Yaf调用,
 * 这些方法, 都接受一个参数:Yaf_Dispatcher $dispatcher
 * 调用的次序, 和申明的次序相同
 */
class Bootstrap extends Yaf_Bootstrap_Abstract{
        public function _initdbfunction() {
                $basedir = $_SERVER[ ‘DOCUMENT_ROOT‘];
                $dbfunction = $basedir.‘/application/functions/db.sae.function.php‘;
                Yaf_Loader::import($dbfunction);               
        }
}

此时修改index.php为:

php
define("APP_PATH",  dirname(__FILE__));
$app  = new Yaf_Application(APP_PATH . "/conf/application.ini");
$app
 ->bootstrap()
 ->run();

这时就大功告成了,我们写一个测试的例子来测试下:我们修改下控制器Test.php代码

php
class TestController extends Yaf_Controller_Abstract {
    public function init(){
           /* 首先关闭自动渲染 */
           Yaf_Dispatcher::getInstance()->disableView();
        }

   public function indexAction() {
           //test db function
           $sql = "select * from mysqldemo where id=1";
           $result = get_line($sql);
           var_dump($result);
       $this->initView();
       $this->display("lazy", array("content" => "this comes from test controller index action"));
       //注意第一个参数直接写lazy就行,写成lazy.phtml会出错
   }
}
?>

注意我们已经使用了get_line()函数哦,访问http://3.lazydemo.sinaapp.com/test 看到输出

array(3) { ["id"]=> string(1) "1" ["content"]=> string(12) "This num is1" ["timeline"]=> string(19) "2012-10-23 13:55:21" } this comes from test controller index action

嘿嘿,说明我们已经成功的添加了SAE 数据库的操作函数。另外这次修改中我还加上了开源的前端模版bootstrap。

实例站点demo

http://3.lazydemo.sinaapp.com/

效果图:

技术分享

代码代码下载:

http://3.lazydemo.sinaapp.com/SAE_Yaf_demo.zip

Sina App Engine(SAE)教程(11)- Yaf使用


推荐阅读
  • 本文深入探讨了在Android应用开发中常见的相机连接故障问题,特别是在RK3288平台和Android 6.0系统上。通过分析具体案例,本文提供了详细的解决方案和应对策略,旨在帮助开发者有效解决相机连接问题,提升应用的稳定性和用户体验。 ... [详细]
  • Spring框架入门指南:专为新手打造的详细学习笔记
    Spring框架是Java Web开发中广泛应用的轻量级应用框架,以其卓越的功能和出色的性能赢得了广大开发者的青睐。本文为初学者提供了详尽的学习指南,涵盖基础概念、核心组件及实际应用案例,帮助新手快速掌握Spring框架的核心技术与实践技巧。 ... [详细]
  • 深入解析Tomcat:开发者的实用指南
    深入解析Tomcat:开发者的实用指南 ... [详细]
  • 从用户转型为开发者:一场思维升级的旅程 | 专访 StarRocks Committer 周威
    从用户转变为开发者,不仅是一次角色的转换,更是一场深刻的思维升级之旅。本次专访中,StarRocks Committer 周威分享了他如何在这一过程中逐步提升技术能力与思维方式,为开源社区贡献自己的力量。 ... [详细]
  • 为了优化直播应用底部聊天框的弹出机制,确保在不同设备上的布局稳定性和兼容性,特别是在配备虚拟按键的设备上,我们对用户交互流程进行了调整。首次打开应用时,需先点击首个输入框以准确获取键盘高度,避免直接点击第二个输入框导致的整体布局挤压问题。此优化通过调整 `activity_main.xml` 布局文件实现,确保了更好的用户体验和界面适配。 ... [详细]
  • 深入解析 Android Drawable:第六阶段进阶指南 ... [详细]
  • Android ListView 自定义 CheckBox 实现列表项多选功能详解
    本文详细介绍了在Android开发中如何在ListView的每一行添加CheckBox,以实现列表项的多选功能。用户不仅可以通过点击复选框来选择项目,还可以通过点击列表的任意一行来完成选中操作,提升了用户体验和操作便捷性。同时,文章还探讨了相关的事件处理机制和布局优化技巧,帮助开发者更好地实现这一功能。 ... [详细]
  • 在2020年8月19日的深度分析中,我们探讨了HTML标签中同时存在`a`标签的`href`和`onclick`属性时的触发顺序问题。此外,还讨论了如何在一个自适应高度的父级`div`中,使两个子`div`中的一个固定高度为300px,另一个自动填充剩余空间的方法。最后,文章详细介绍了JavaScript异步加载的多种实现方式,包括但不限于`async`、`defer`属性以及动态脚本插入技术,为开发者提供了丰富的技术参考。 ... [详细]
  • 在Adobe After Effects中,通过高效添加地图指北针,可以显著提升地理信息的准确性和视觉效果。本文介绍了一种方法,利用代码函数 `public static void ExportMapEx(string filepath, int resolution, AxMapControl curMapControl)`,实现地图导出时自动添加指北针,确保地理数据的精确性和一致性。此外,还详细探讨了如何优化指北针的位置和样式,以增强地图的可读性和专业性。 ... [详细]
  • 在 Asp.net 应用中,动态加载 DropDownList 控件的数据源是一项常见需求。本文探讨了如何高效地从数据库中获取数据,并实时更新下拉列表,确保用户界面始终与后台数据保持同步。通过使用 ADO.NET 和 LINQ to SQL 技术,开发者可以轻松实现这一功能,同时提高应用的性能和用户体验。文中还提供了代码示例和最佳实践,帮助开发者解决常见的数据绑定问题。 ... [详细]
  • Go语言中的高效排序与搜索算法解析
    在探讨Go语言中高效的排序与搜索算法时,本文深入分析了Go语言提供的内置排序功能及其优化策略。通过实例代码,详细讲解了如何利用Go语言的标准库实现快速、高效的排序和搜索操作,为开发者提供了实用的编程指导。 ... [详细]
  • 点击Tab标签切换不同查询数据,并选择数据存入缓存实现两个界面带参数跳转
    项目场景:在不同的tab标签页中点击不同的标签页查找不同的内容,然后选中其中一个页面中的一条数据将此数据某个信息选中然后存入session缓存当中然后另一个界面从s ... [详细]
  • AppDomain是CLR的运行单元,它可以加载Assembly、创建对象以及执行程序。AppDomain是CLR实现代码隔离的基本机制。每一个AppDomain可以 ... [详细]
  • 配置php连接mysql,PHP连接
    本文目录一览:1、dw中php怎么连接mysql数据库 ... [详细]
  • 用FileStream,是没办法下载指定文件的,不管你怎么写,都是浪费力气,最后下载的是整个html页面,包括背景,按钮,查询框,图片,虽然还是xsl格式。而且关闭文档,会弹出是否保存当前修改,如果保 ... [详细]
author-avatar
浪漫满屋19860902692
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有