ZendFramework 学习
Mar 7
  /**
   * 认证机制
   * Zend_Auth 学习笔记
   * Zend_Auth只涉及 认证而不是授权,后者应该有Zend_Acl设置
   * @author yangjs
   */
  
  class AuthController extends Zend_Controller_Action
  {
    //设置
    public function init()
    {
      $this->initView();
      $this->view->baseUrl=$this->_request->getBaseUrl();  
      $this->view->user=Zend_Auth::getInstance()->getIdentity();//获取认证结果
    }
    /**
     * zend_auth 基础:自定义认证
     */
    public function indexAction()
    {
      $this->_auth= new MyAuthAdapter('root','123456');
      $result = $this->_auth->authenticate();
      switch ($result->getCode()) {

        case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
          print_r($result->getMessages());
            break;
    
        case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
             print_r($result->getMessages());
            break;
    
        case Zend_Auth_Result::SUCCESS:
            print_r($result->getMessages());
            break;
    
        default:
          echo 'else';
            break;
      }
      print_r($_SESSION);
      //$this->_redirect('/'); //重定向到主页
    }
    /**
     * zend_auth 进阶:持久认证
     *
     */
    public function sessionAction(){
      /*
      * 通过给Zend_Auth_Storage_Session的构造器传递不同的值,这个名字空间可以被替换,并且这个值被从内部传递给Zend_Session_Namespace的构造器。
      *  如果认证成功,则有数据自动保存到session中 可以print_r($_SESSION)查看结果
      */
      $auth=Zend_Auth::getInstance();
      $auth->setStorage(new Zend_Auth_Storage_Session('yangjs'));
      $authAdapter=new MyAuthAdapter('root','123456');
      $result=$auth->authenticate($authAdapter);
      // 换一个名字空间
      $auth->setStorage(new Zend_Auth_Storage_Session('yang2'));
      $authAdapter=new MyAuthAdapter('root','123456');
      $result=$auth->authenticate($authAdapter);
      print_r($_SESSION);
      //打印结果:Array ( [yangjs] => Array ( [storage] => 1 ) [yang2] => Array ( [storage] => 1 ) )
      //echo session_save_path(); //可以进入此文件查看session
      #  下面 我们使用自己定义的一个存储类  #
//      $auth->setStorage(new MyStorage());
//      $authAdapter=new MyAuthAdapter('root','1234566');
//      $result = $auth->authenticate($authAdapter);
      
    }
    /**
     * zend_auth高级:登录认证(结合数据库和持久认证)
     *
     */
    public function loginAction()
    {
      $this->view->title='login in';
      if($this->_request->isPost()){
        Zend_Loader::loadClass('Zend_Filter_StripTags');
        $f=new Zend_Filter_StripTags();
        $username=$f->filter($this->_request->getPost('username'));
        $password=$f->filter($this->_request->getPost('password'));
        if(empty($username)){
          die('your username is empty!');
        }else{
          Zend_Loader::loadClass('Zend_Auth_Adapter_DbTable');
          $db=Zend_Registry::get('db');  //获取db实例
          $authAdapter=new Zend_Auth_Adapter_DbTable($db);  //获取db认证实例
          $authAdapter->setTableName('users');  //设置db认证表名
          $authAdapter->setIdentityColumn('username');  //需认证的列
          $authAdapter->setCredentialColumn('password');  //对应的列为PASSWORD
          $authAdapter->setIdentity($username);      //设置认证列值
          $authAdapter->setCredential($password);      //设置对应列值
          $auth=Zend_Auth::getInstance();          //获取认证结果实例
          $result=$auth->authenticate($authAdapter);    //根据db认证实例返回认证结果  
          if($result->isValid()){              //如果成功
            $data=$authAdapter->getResultRowObject(null,'password');
            $auth->getStorage()->write($data);      //保存结果
            $this->_redirect('/auth');
          }else{                      //如果失败
            $this->view->message='login failed';
          }
        }
      }
    }
    /**
     * Zend_auth登出
     *
     */
    public function logoutAction()
    {
      Zend_Auth::getInstance()->clearIdentity();
      $this->_redirect('/auth/login');
    }
  }

以下为自定义认证类:/application/models/MyAuthAdapter.php

<?php
  //自定义认证判断类
  class MyAuthAdapter implements Zend_Auth_Adapter_Interface
  {
    private $user;
    private $pass;
    public function __construct($user,$pass){
      $this->user  = $user;
      $this->pass = $pass;
    }
    /**
     * @desc 验证
     *
     * @return unknown
     */
    public function authenticate(){
      if($this->user == 'root' && $this->pass=='123456'){
        $flag = 1;
        $identity = true;
        $messages = array('content'=>'正确的用户');
      }else{
        $flag = 0;
        $identity = false;
        $messages = array('content'=>'用户名或密码错误');
      }
      $r=new  Zend_Auth_Result($flag,$identity,$messages);
      return $r;
    }
  }
Feb 21
/**
* 权限控制
* Zend权限控制demo(学习笔记)
* @author yangjs
*
*/
class AclController extends Zend_Controller_Action
{
//保护动作 不能加到auth控制器中 否则未登录时会一直循环
public function preDispatch()
{
$auth=Zend_Auth::getInstance();
if(!$auth->hasIdentity()){
$this->_redirect('/auth/login');
}
}
public function indexAction()
{
$acl = new Zend_Acl();
$acl->addRole(new Zend_Acl_Role('guest'))
    ->addRole(new Zend_Acl_Role('member'))
    ->addRole(new Zend_Acl_Role('admin'));
$parents = array('guest','member','admin'); //父权限
$acl->addRole(new Zend_Acl_Role('yangjs'),$parents);//添加一个子角色
$acl->add(new Zend_Acl_Resource('editmytxt'));//新增一个资源权限(模块功能)
$acl->deny('guest','editmytxt');//拒绝给予该权限给guest
$acl->allow('member','editmytxt');//给予该权限给member
echo $acl->isAllowed('yangjs', 'editmytxt') ? 'allowed' : 'denied'; //看看yangjs有没有权限
//allowed
/*
1.为什么会是allowed 当为一个角色指定多重父(角色)时,
请记住,对于一个授权查询的可用规则,最后列出的父(角色)是首先被搜索的。
这里member优先guest被查到
2.实例化ACL后,Zend默认是拒绝任何role对resource的访问,除非指明了allow
*/
}

/**
* 一个CMS权限系统的例子
*
*/
public function cmsAction()
{
echo '
##########  基础功能   ##########
';
//增加好角色
$acl = new Zend_Acl();
$roleGuest = new Zend_Acl_Role('guest'); //新增一个Role
$acl->addRole($roleGuest);        //添加到注册表
$acl->addRole(new Zend_Acl_Role('staff'),$roleGuest); //新角色staff从guest继承
$acl->addRole(new Zend_Acl_Role('editor'), 'staff');  //新角色editor从staff继承 (另外一种写法)
$acl->addRole(new Zend_Acl_Role('administrator'));    //新建管理员角色    
//权限分配
$acl->allow('guest',null,'view');   //角色guest只有view权限
$acl->allow('staff',null,array('edit', 'submit', 'revise'));  //角色staff有其他更多权限
$acl->allow('editor',null,array('add','del'));  //角色editor有其他更多权限
$acl->allow('administrator');    //管理员有所有权限
/**
*  allow中的null 的值用来表明 allow 规则适用于所有的 resources。
*/
//权限结果考证
echo $acl->isAllowed('guest', null, 'view') ? "allowed" : "denied";   //allowed 已分配
echo $acl->isAllowed('staff', null, 'add') ? "allowed" : "denied";     //denied 未分配
echo $acl->isAllowed('editor', null, 'submit') ? "allowed" : "denied";  //allowed 继承下来
echo $acl->isAllowed('administrator', null, 'view') ? "allowed" : "denied"; //allowed

echo '
##########  进一步功能   ##########
';
//精细的ACL分配
$acl->addRole(new Zend_Acl_Role('marketing'),'staff');  //继承至staff
//添加一些资源
$acl->add(new Zend_Acl_Resource('newsletter'));
$acl->add(new Zend_Acl_Resource('news'));
$acl->add(new Zend_Acl_Resource('latest'),'news');
$acl->add(new Zend_Acl_Resource('announcement'), 'news');
//权限修改      
$acl->allow('marketing',array('newsletter','latest'),array('add','del'));
$acl->deny('staff','latest','revise');     //禁止staff(包括其继承者,如marketing)对于latest的revise功能
$acl->deny(null, 'announcement', 'del');   //禁止一切角色对announcement的del功能
//权限考证
echo $acl->isAllowed('staff', 'newsletter', 'publish') ?"allowed" : "denied";  //denied 未分配
echo $acl->isAllowed('staff', 'newsletter', 'view') ?"allowed" : "denied";    //allowed 已分配
//移除权限设置
$acl->removedeny('staff','latest','revise');   //除去禁止设置==添加允许设置
$acl->removeallow('marketing','latest','add');  //除去允许设置==添加禁止设置
//权限考证
echo '
';
echo $acl->isAllowed('staff', 'latest', 'revise') ?"allowed" : "denied";  //allowed 已经除去了禁止
echo $acl->isAllowed('marketing', 'latest', 'add') ?"allowed" : "denied";  //denied 已经除去了允许

echo '
##########  高级用法   ##########
';
echo serialize($roleGuest); //可以序列化保存结果
$cleanIp = new CleanIPAssertion();
//使用声明(Assert)来编写条件性的 ACL 规则 只对原来没有的权限有效,如staff 原来就对latest有revise
$acl->allow('marketing', 'latest','add',  new CleanIPAssertion());
$acl->deny('staff', 'latest','revise',  new CleanIPAssertion());
echo $acl->isAllowed('marketing', 'latest', 'add') ?"allowed" : "denied";//allowed 设定了CleanIPAssertion返回结果都是true
echo $acl->isAllowed('staff', 'latest', 'revise') ?"allowed" : "denied";//denied 设定了CleanIPAssertion返回结果都是true
echo '
##########  ACL学习结束   ##########
';
}
}




/applcation/models/CleanIPAssertion.php

class CleanIPAssertion implements Zend_Acl_Assert_Interface
{
    public function assert(Zend_Acl $acl,
                           Zend_Acl_Role_Interface $role = null,
                           Zend_Acl_Resource_Interface $resource = null,
                           $privilege = null)
    {
        return $this->_isCleanIP($_SERVER['REMOTE_ADDR']);
    }

    protected function _isCleanIP($ip)
    {
      //... 判断IP是否合法 假设所有IP都不合法 则调用了此类后 所有权限都没了
      return true;
    }
}
Feb 20
1.学习完后的目录结构
/www                     (项目根目录)
—/application           (应用程序目录)
——/controllers        (控制器)
——/models            (模型)
——/layouts            (整体布局)
——/views              (视图)
———/helpers         (视图帮助函数)
———/scripts          (模板文件存放地址)
————/index        (index控制器模板文件存放地址)
—/library                (扩展库)
——/zend              (ZEND库目录)
—/public                (网站根目录)
——/css                 (样式)
——/images            (图片)
——/js                   (js)
——index.php         (网站入口)
——.htaccess      

2.首页分析 (/www/public/index.php)
//错误开启
error_reporting(E_ALL|E_STRICT);
ini_set('display_errors', 1);
//时区设置
date_default_timezone_set('PRC');
// 目录设置和类装载
set_include_path('.' . PATH_SEPARATOR . '../library/'
. PATH_SEPARATOR . '../application/models'
. PATH_SEPARATOR . get_include_path());
require_once "Zend/Loader/Autoloader.php";
Zend_Loader_Autoloader::getInstance()->setFallbackAutoloader(true);
//配置文件
$config = new Zend_Config_Ini('../application/config.ini','general'); //取general节
$registry = Zend_Registry::getInstance();
//将配置文件注册到zend注册表中
$registry->set('config',$config);
// 数据库设置
$db=Zend_Db::factory($config->db);
Zend_Db_Table::setDefaultAdapter($db);
// 设置控制器
$frontController = Zend_Controller_Front::getInstance();
$frontController->throwExceptions(true);
$frontController->setControllerDirectory('../application/controllers');
//网站跟目录
$frontController->setBaseUrl('/');
// 通知启用公有布局脚本 路径为layouts目录下
Zend_Layout::startMvc(array('layoutPath'=>'../application/layouts'));
// run!
$frontController->dispatch();

3.INDEX控制器分析(/www/application/controllers/IndexController.php)

class IndexController Extends Zend_Controller_Action {

public function indexAction(){
$this->view->title='list';
//实例化Cd模型
$cd=new Cd();
//获取表内所有数据
$this->view->cd=$cd->fetchAll();
}

public function addAction(){
$this->view->title='add';
$cdform = new CdForm();
//设置添加按钮
$cdform->submit->setLabel('Add');
$this->view->cdfrom=$cdform;  //将表单保存到视图form属性中
if($this->_request->isPost()){  //如果有表单提交动作
$formData = $this->_request->getPost();//获取数据
if($cdform->isValid($formData)){//验证表单数据是否有效
$cd = new Cd();
$row = $cd->createRow();//新加一行数据
$row->artist = $cdform->getValue('artist');
$row->title = $cdform->getValue('title');
$row->save();
$this->_redirect('/'); //重定向到主页
}else{
$cdform->populate($formData);//将用户输入的数据返回给用户
}  
}

}

public function editAction(){
$this->view->title='edit';
$cdform = new CdForm();
$cdform->submit->setLabel('Save'); //设置添加按钮
$this->view->cdfrom=$cdform;  //将表单保存到视图form属性中
if($this->_request->isPost()){  //如果有表单提交动作
$formData = $this->_request->getPost();//获取数据
if($cdform->isValid($formData)){//验证表单数据是否有效
$cd = new Cd();
$id = (int)$cdform->getValue('id');
$row = $cd->fetchRow('id='.$id);//新加一行数据
$row->artist = $cdform->getValue('artist');
$row->title = $cdform->getValue('title');
$row->save();
$this->_redirect('/'); //重定向到主页
}else{
$cdform->populate($formData);//将用户输入的数据返回给用户
}  
}else{//显示需要修改的内容
$id=$this->_request->getParam('id',0);
if($id>0){
$cd = new Cd();
$cd = $cd->fetchRow('id='.$id);
$cdform->populate($cd->toArray());
}

}

}

public function deleteAction(){
$this->view->title='remove';
$cd = new Cd();  //实例化一个光盘类
if($this->_request->isPost()){
$id=(int)$this->_request->getPost('id'); //得到删除的ID
$del=$this->_request->getPost('del');   //得到删除的信号
if($del =='yes' && $id>0){          //确定删除
$cd->delete('id='.$id);
}
$this->_redirect('/');  //返回主页(其实是下一步操作)
}else{
$id=(int)$this->_request->getParam('id');
if($id>0){
$this->view->cd=$cd->fetchRow('id='.$id); //填充数据
}
}
}
}

4.CD模型分析(/www/application/models/Cd.php)

class Cd extends Zend_Db_Table {
protected $_name="zend_cd"; //数据表名
}

5.CD表单模型分析(/www/application/models/CdForm.php)
class CdForm extends Zend_Form{
  public function __construct($options=null){
    parent::__construct($options);
    $this->setName('cd');
    $id = new Zend_Form_Element_Hidden('id');
    $artist = new Zend_Form_Element_Text('artist');
    $artist->setLabel('Artist')
      ->setRequired(true)
      ->addFilter('StripTags')  //过滤掉不必要的HTML
      ->addFilter('StringTrim')  //过滤掉不必要的空格
      ->addValidator('NotEmpty');  //用户输入不能为空
    $title = new Zend_Form_Element_Text('title');
    $title->setLabel('Title')
      ->setRequired(true)
      ->addFilter('StripTags')
      ->addFilter('StringTrim')
      ->addValidator('NotEmpty');
    $submit = new Zend_Form_Element_Submit('submit');
    $submit->setAttrib('id','submitbutton');
    $this->addElements(array($id,$artist,$title,$submit));  
  }
}  

6.配置文件(/www/application/config.ini)
[general]
db.adapter=PDO_MYSQL
db.params.host = localhost
db.params.username = root
db.params.password = 123456
db.params.dbname = test
db.params.driver_options.1002 = "SET NAMES UTF8;"  //字符编码

7.视图辅助函数getBaseUrl(/www/application/views/helpers/baseUrl.php)
class Zend_View_Helper_BaseUrl{
function baseUrl(){
$fc=Zend_Controller_Front::getInstance();
return $fc->getBaseUrl();
}  
}

这样,视图中就可以直接调用了
<?php echo $this->baseUrl();?>
Feb 20
Fatal error: Uncaught exception 'Zend_Db_Adapter_Exception' with message 'The mysql driver is not currently installed' in K:\www\zend\www\library\Zend\Db\Adapter\Pdo\Abstract.php:112 Stack trace: #0 K:\www\zend\www\library\Zend\Db\Adapter\Pdo\Mysql.php(96): Zend_Db_Adapter_Pdo_Abstract->_connect() #1 K:\www\zend\www\library\Zend\Db\Adapter\Abstract.php(448): Zend_Db_Adapter_Pdo_Mysql->_connect() #2 K:\www\zend\www\library\Zend\Db\Adapter\Pdo\Abstract.php(238): Zend_Db_Adapter_Abstract->query('DESCRIBE `zend_...', Array) #3 K:\www\zend\www\library\Zend\Db\Adapter\Pdo\Mysql.php(156): Zend_Db_Adapter_Pdo_Abstract->query('DESCRIBE `zend_...') #4 K:\www\zend\www\library\Zend\Db\Table\Abstract.php(823): Zend_Db_Adapter_Pdo_Mysql->describeTable('zend_cd', NULL) #5 K:\www\zend\www\library\Zend\Db\Table\Abstract.php(862): Zend_Db_Table_Abstract->_setupMetadata() #6 K:\www\zend\www\library\Zend\Db\Table\Abstract.php(969): Zend_Db_Table_Abstract->_setupPrimaryKey() #7 K:\www\zend\www\library\Zend\Db\Table\Select.php(100): Zend_Db_Ta in K:\www\zend\www\library\Zend\Db\Adapter\Pdo\Abstract.php on line 112



-----------------------------
Zend_Db需要pdo扩展的支持才可以运行
打开php.ini,找到以下两行,
;extension=php_pdo.dll
;extension=php_pdo_mysql.dll
将前面的分号去掉,保存后重启apache。

如果没用;extension=php_pdo_mysql.dll 这项 请自行添加



Feb 18
Fatal error: Uncaught exception 'Zend_Controller_Dispatcher_Exception' with message 'Invalid controller specified (index)' in E:\www\zend\www\library\zend\Controller\Dispatcher\Standard.php:248 Stack trace: #0 E:\www\zend\www\library\zend\Controller\Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http)) #1 E:\www\zend\www\public\index.php(18): Zend_Controller_Front->dispatch() #2 {main} thrown in E:\www\zend\www\library\zend\Controller\Dispatcher\Standard.php on line 248




参考:http://wenku.baidu.com/view/984dd320dd36a32d737581f6.html
分页: 1/2 第一页 1 2 下页 最后页 [ 显示模式: 摘要 | 列表 ]