目錄
Zend Framework开发入门经典教程,zendframework
News
Add News
Comments
Add a Comment
您可能感兴趣的文章:
首頁 後端開發 php教程 Zend Framework开发入门经典教程,zendframework_PHP教程

Zend Framework开发入门经典教程,zendframework_PHP教程

Jul 12, 2016 am 08:56 AM
framework zend 入門

Zend Framework开发入门经典教程,zendframework

本文讲述了Zend Framework开发入门相关知识点。分享给大家供大家参考,具体如下:

Zend Framework发布了!虽然仍处于开发初期,这个教程仍突出讲解目前几个最好的功能,并指导你完成一个简单程序的构建。

Zend最早在社区里发布了ZF。基于同样的想法,这个教程写来用于展示ZF现有的功能。由于这个教程是在线发布,我将在ZF变化时对其进行更新,以便尽可能有效。

要求

Zend Framework要求PHP5。为了更好利用本教程的代码,你还需要Apache网页服务器。因为示范程序(一个新闻管理系统)用到了mod_rewrite。

这个教程的代码可以自由下载,所以你可以自己试一下。你可以从Brain Buld的网站下载到代码:http://brainbulb.com/zend-framework-tutorial.tar.gz。

下载ZF

当你开始这篇教程时,你需要下载ZF的最新版本。你可以用浏览器手工从http://framework.zend.com/download选择tar.gz或zip文件进行下载,或者使用下列命令:

$ wget http://framework.zend.com/download/tgz
$ tar -xvzf ZendFramework-0.1.2.tar.gz

登入後複製

提示:Zend计划提供自有PEAR通道简化下载。

一旦你下载了预览版,把library目录放到方便的地方。在这个教程,我把library重命名为lib以便有个简洁的目录结构:

app/
views/
controllers/
www/
.htaccess
index.php
lib/

www目录是文档根目录,controllers和views目录是以后会用到的空目录,而lib目录来自你下载的预览版。

开始

我要介绍的第一个组件是Zend_Controller。从很多方面看,它为你开发的程序提供了基础,同时也部分决定了Zend Framework不只是个组件的集合。但是,你在用之前需要将所有的得到的请求都放到一个简单的PHP脚本。本教程用的是mod_rewrite。

用mod_rewrite自身是一种艺术,但幸运的是,这个特殊的任务特别简单。如果你对mod_rewrite或Apache的一般配置不熟悉,在文档根目录下创建一个.htaccess文件,并添加以下内容:

RewriteEngine on
RewriteRule !/.(js|ico|gif|jpg|png|css)$ index.php

登入後複製

提示: Zend_Controller的一个TODO项目就是取消对mod_rewrite的依赖。为了提供一个预览版的范例,本教程用了mod_rewrite。

如果你直接把这些内容添加到httpd.conf,你必须重启网页服务器。但如果你用.htaccess文件,则什么都不必做。你可以放一些具体的文本到index.php并访问任意路径如/foo/bar做一下快速测试。如你的域名为example.org,则访问http://example.org/foo/bar。

你还要设置ZF库的路径到include_path。你可以在php.ini设置,也可以直接在你的.htaccess文件放下列内容:

php_value include_path "/path/to/lib"

登入後複製

Zend

Zend类包含了一些经常使用的静态方法的集合。下面是唯一一个你要手工添加的类:

<&#63;php
include 'Zend.php';
&#63;>

登入後複製

一旦你包含了Zend.php,你就已经包含了Zend类的所有的类方法。用loadClass()就可以简单地加载其它类。例如,加载Zend_Controller_Front类:

<&#63;php
include 'Zend.php';
Zend::loadClass('Zend_Controller_Front');
&#63;>

登入後複製

include_path能理解loadclass()及ZF的组织和目录结构。我用它加载所有其它类。

Zend_Controller

使用这个controller非常直观。事实上,我写本教程时并没有用到它丰富的文档。

提示:文档目前已经可以在http://framework.zend.com/manual/zend.controller.html看到。

我一开始是用一个叫Zend_Controller_Front的front controller。为了理解它是怎么工作的,请把下列代码放在你的index.php文件:

<&#63;php
include 'Zend.php';
Zend::loadClass('Zend_Controller_Front');
$controller = Zend_Controller_Front::getInstance();
$controller->setControllerDirectory('/path/to/controllers');
$controller->dispatch();
&#63;>

登入後複製

如果你更喜欢对象链结,可以用以下代码代替:

<&#63;php
include 'Zend.php';
Zend::loadClass('Zend_Controller_Front');
$controller = Zend_Controller_Front::getInstance()
       ->setControllerDirectory('/path/to/controllers')
       ->dispatch();
&#63;>

登入後複製

现在如果你访问/foo/bar,会有错误发生。没错!它让你知道发生了什么事。主要的问题是找不到IndexController.php文件。

在你创建这个文件之前,应先理解一下ZF想让你怎样组织这些事情。ZF把访问请求给拆分开来。假如访问的是/foo/bar,则foo是controller,而bar是action。它们的默认值都是index.

如果foo是controller,ZF就会去查找controllers目录下的FooController.php文件。因为这个文件不存在,ZF就退回到IndexController.php。结果都没有找到,就报错了。

接下来,在controllers目录创建IndexController.php文件(可以用setControllerDirectory()设置):

<&#63;php
Zend::loadClass('Zend_Controller_Action');
class IndexController extends Zend_Controller_Action 
{
  public function indexAction()
  {
    echo 'IndexController::indexAction()';
  }
}
&#63;>

登入後複製

就如刚才说明的,IndexController类处理来自index controller或controller不存在的请求。indexAction()方法处理action为index的访问。要记住的是index是controller和action的默认值。如果你访问/,/index或/index/index,indexAction()方法就会被执行。 (最后面的斜杠并不会改变这个行为。) 而访问其他任何资源只会导致出错。

在继续做之前,还要在IndexController加上另外一个有用的类方法。不管什么时候访问一个不存在的控制器,都要调用noRouteAction()类方法。例如,在FooController.php不存在的条件下,访问/foo/bar就会执行noRouteAction()。但是访问/index/foo仍会出错,因为foo是action,而不是controller.

将noRouteAction()添加到IndexController.php:

<&#63;php
Zend::loadClass('Zend_Controller_Action');
class IndexController extends Zend_Controller_Action 
{
  public function indexAction()
  {
    echo 'IndexController::indexAction()';
  }
  public function noRouteAction()
  {
    $this->_redirect('/');
  }
}
&#63;>

登入後複製

例子中使用$this->_redirect('/')来描述执行noRouteAction()时,可能发生的行为。这会将对不存在controllers的访问重定向到根文档(首页)。

现在创建FooController.php:

<&#63;php
Zend::loadClass('Zend_Controller_Action');
class FooController extends Zend_Controller_Action 
{
  public function indexAction()
  {
    echo 'FooController::indexAction()';
  }
  public function barAction()
  {
    echo 'FooController::barAction()';
  }
}
&#63;>

登入後複製

如果你再次访问/foo/bar,你会发现执行了barAction(),因为bar是action。现在你不只支持了友好的URL,还可以只用几行代码就做得这么有条理。酷吧!
你也可以创建一个__call()类方法来处理像/foo/baz这样未定义的action。

<&#63;php
Zend::loadClass('Zend_Controller_Action');
class FooController extends Zend_Controller_Action 
{
  public function indexAction()
  {
    echo 'FooController::indexAction()';
  }
  public function barAction()
  {
    echo 'FooController::barAction()';
  }
  public function __call($action, $arguments)
  {
    echo 'FooController:__call()';
  }
}
&#63;>

登入後複製

现在你只要几行代码就可以很好地处理用户的访问了,准备好继续。

Zend_View

Zend_View是一个用来帮助你组织好你的view逻辑的类。这对于模板-系统是不可知的,为了简单起见,本教程不使用模板。如果你喜欢的话,不妨用一下。

记住,现在所有的访问都是由front controller进行处理。因此应用框架已经存在了,另外也必须遵守它。为了展示Zend_View的一个基本应用,将IndexController.php修改如下:

<&#63;php
Zend::loadClass('Zend_Controller_Action');
Zend::loadClass('Zend_View');
class IndexController extends Zend_Controller_Action 
{
  public function indexAction()
  {
    $view = new Zend_View();
    $view->setScriptPath('/path/to/views');
    echo $view->render('example.php');
  }
  public function noRouteAction()
  {
    $this->_redirect('/');
  }
}
&#63;>

登入後複製

在views目录创建example.php文件:

<html>
<head>
  <title>This Is an Example</title>
</head>
<body>
  <p>This is an example.</p>
</body>
</html>

登入後複製

现在,如果你访问自己网站的根资源,你会看到example.php的内容。这仍没什么用,但你要清楚你要在以一种结构和组织非常清楚的方式在开发网络应用。

为了让Zend_View的应用更清楚一点,,修改你的模板(example.php)包含以下内容:

<html>
<head>
  <title><&#63;php echo $this->escape($this->title); &#63;></title>
</head>
<body>
  <&#63;php echo $this->escape($this->body); &#63;>
</body>
</html>

登入後複製

现在已经添加了两个功能。$this->escape()类方法用于所有的输出。即使你自己创建输出,就像这个例子一样。避开所有输出也是一个很好的习惯,它可以在默认情况下帮助你防止跨站脚本攻击(XSS)。

$this->title和$this->body属性用来展示动态数据。这些也可以在controller中定义,所以我们修改IndexController.php以指定它们:

<&#63;php
Zend::loadClass('Zend_Controller_Action');
Zend::loadClass('Zend_View');
class IndexController extends Zend_Controller_Action 
{
  public function indexAction()
  {
    $view = new Zend_View();
    $view->setScriptPath('/path/to/views');
    $view->title = 'Dynamic Title';
    $view->body = 'This is a dynamic body.';
    echo $view->render('example.php');
  }
  public function noRouteAction()
  {
    $this->_redirect('/');
  }
}
&#63;>

登入後複製

现在你再次访问根目录,应该就可以看到模板所使用的这些值了。因为你在模板中使用的$this就是在Zend_View范围内所执行的实例。

要记住example.php只是一个普通的PHP脚本,所以你完全可以做你想做的。只是应努力只在要求显示数据时才使用模板。你的controller (controller分发的模块)应处理你全部的业务逻辑。

在继续之前,我想做最后一个关于Zend_View的提示。在controller的每个类方法内初始化$view对象需要额外输入一些内容,而我们的主要目标是让快速开发网络应用更简单。如果所有模板都放在一个目录下,是否要在每个例子中都调用setScriptPath()也存在争议。

幸运的是,Zend类包含了一个寄存器来帮助减少工作量。你可以用register()方法把你的$view对象存储在寄存器:

<&#63;php
Zend::register('view', $view);
&#63;>

登入後複製

用registry()方法进行检索:

<&#63;php
$view = Zend::registry('view');
&#63;>

登入後複製

基于这点,本教程使用寄存器。

Zend_InputFilter

本教程讨论的最后一个组件是Zend_InputFilter。这个类提供了一种简单而有效的输入过滤方法。你可以通过提供一组待过滤数据来进行初始化。

<&#63;php
$filterPost = new Zend_InputFilter($_POST);
&#63;>

登入後複製

这会将($_POST)设置为NULL,所以就不能直接进入了。Zend_InputFilter提供了一个简单、集中的根据特定规则过滤数据的类方法集。例如,你可以用getAlpha()来获取$_POST['name']中的字母:

<&#63;php
/* $_POST['name'] = 'John123Doe'; */
$filterPost = new Zend_InputFilter($_POST);
/* $_POST = NULL; */
$alphaName = $filterPost->getAlpha('name');
/* $alphaName = 'JohnDoe'; */
&#63;>

登入後複製

每一个类方法的参数都是对应要过滤的元素的关键词。对象(例子中的$filterPost)可以保护数据不被篡改,并能更好地控制对数据的操作及一致性。因此,当你操纵输入数据,应始终使用Zend_InputFilter。

提示:Zend_Filter提供与Zend_InputFilter方法一样的静态方法。

构建新闻管理系统

虽然预览版提供了许多组件(甚至许多已经被开发),我们已经讨论了构建一个简单程序所需要的全部组件。在这里,你会对ZF的基本结构和设计有更清楚的理解。

每个人开发的程序都会有所不同,而Zend Framework试图包容这些差异。同样,这个教程是根据我的喜好写的,请根据自己的偏好自行调整。

当我开发程序时,我会先做界面。这并不意味着我把时间都花在标签、样式表和图片上,而是我从一个用户的角度去考虑问题。因此我把程序看成是页面的集合,每一页都是一个独立的网址。这个新闻系统就是由以下网址组成的:

/
/add/news
/add/comment
/admin
/admin/approve
/view/{id}

你可以直接把这些网址和controller联系起来。IndexController列出新闻,AddController添加新闻和评论,AdminController处理一些如批准新闻之类的管理,ViewController特定新闻和对应评论的显示。

如果你的FooController.php还在,把它删除。修改IndexController.php,为业务逻辑以添加相应的action和一些注释:

<&#63;php
Zend::loadClass('Zend_Controller_Action');
class IndexController extends Zend_Controller_Action 
{
  public function indexAction()
  {
    /* List the news. */
  }
  public function noRouteAction()
  {
    $this->_redirect('/');
  }
}
&#63;>

登入後複製

接下来,创建AddController.php文件:

<&#63;php
Zend::loadClass('Zend_Controller_Action');
class AddController extends Zend_Controller_Action
{
  function indexAction()
  {
    $this->_redirect('/');
  }
  function commentAction()
  {
    /* Add a comment. */
  }
  function newsAction()
  {
    /* Add news. */
  }
  function __call($action, $arguments)
  {
    $this->_redirect('/');
  }
}
&#63;>

登入後複製

记住AddController的indexAction()方法不能调用。当访问/add时会执行这个类方法。因为用户可以手工访问这个网址,这是有可能的,所以你要把用户重定向到主页、显示错误或你认为合适的行为。

接下来,创建AdminController.php文件:

<&#63;php
Zend::loadClass('Zend_Controller_Action');
class AdminController extends Zend_Controller_Action
{
  function indexAction()
  {
    /* Display admin interface. */
  }
  function approveAction()
  {
    /* Approve news. */
  }
  function __call($action, $arguments)
  {
    $this->_redirect('/');
  }
}
&#63;>

登入後複製

最后,创建ViewController.php文件:

<&#63;php
Zend::loadClass('Zend_Controller_Action');
class ViewController extends Zend_Controller_Action
{
  function indexAction()
  {
    $this->_redirect('/');
  }
  function __call($id, $arguments)
  {
    /* Display news and comments for $id. */
  }
}
&#63;>

登入後複製

和AddController一样,index()方法不能调用,所以你可以使用你认为合适的action。ViewController和其它的有点不同,因为你不知道什么才是有效的action。为了支持像/view/23这样的网址,你要使用__call()来支持动态action。

数据库操作

因为Zend Framework的数据库组件还不稳定,而我希望这个演示可以做得简单一点。我使用了一个简单的类,用SQLite进行新闻条目和评论的存储和查询。

<&#63;php
class Database
{
  private $_db;
  public function __construct($filename)
  {
    $this->_db = new SQLiteDatabase($filename);
  }
  public function addComment($name, $comment, $newsId)
  {
    $name = sqlite_escape_string($name);
    $comment = sqlite_escape_string($comment);
    $newsId = sqlite_escape_string($newsId);
    $sql = "INSERT
        INTO  comments (name, comment, newsId)
        VALUES ('$name', '$comment', '$newsId')";
    return $this->_db->query($sql);
  }
  public function addNews($title, $content)
  {
    $title = sqlite_escape_string($title);
    $content = sqlite_escape_string($content);
    $sql = "INSERT
        INTO  news (title, content)
        VALUES ('$title', '$content')";
    return $this->_db->query($sql);
  }
  public function approveNews($ids)
  {
    foreach ($ids as $id) {
      $id = sqlite_escape_string($id);
      $sql = "UPDATE news
          SET  approval = 'T'
          WHERE id = '$id'";
      if (!$this->_db->query($sql)) {
        return FALSE;
      }
    }
    return TRUE;
  }
  public function getComments($newsId)
  {
    $newsId = sqlite_escape_string($newsId);
    $sql = "SELECT name, comment
        FROM  comments
        WHERE newsId = '$newsId'";
    if ($result = $this->_db->query($sql)) {
      return $result->fetchAll();
    }
    return FALSE;
  }
  public function getNews($id = 'ALL')
  {
    $id = sqlite_escape_string($id);
    switch ($id) {
      case 'ALL':
        $sql = "SELECT id,
                title
            FROM  news
            WHERE approval = 'T'";
        break;
      case 'NEW':
        $sql = "SELECT *
            FROM  news
            WHERE approval != 'T'";
        break;
      default:
        $sql = "SELECT *
            FROM  news
            WHERE id = '$id'";
        break;
    }
    if ($result = $this->_db->query($sql)) {
      if ($result->numRows() != 1) {
        return $result->fetchAll();
      } else {
        return $result->fetch();
      }
    }
    return FALSE;
  }
}
&#63;>

登入後複製

(你可以用自己的解决方案随意替换这个类。这里只是为你提供一个完整示例的介绍,并非建议要这么实现。)

这个类的构造器需要SQLite数据库的完整路径和文件名,你必须自己进行创建。

<&#63;php
$db = new SQLiteDatabase('/path/to/db.sqlite');
$db->query("CREATE TABLE news (
    id    INTEGER PRIMARY KEY,
    title  VARCHAR(255),
    content TEXT,
    approval CHAR(1) DEFAULT 'F'
  )");
$db->query("CREATE TABLE comments (
    id    INTEGER PRIMARY KEY,
    name   VARCHAR(255),
    comment TEXT,
    newsId  INTEGER
  )");
&#63;>

登入後複製

你只需要做一次,以后直接给出Database类构造器的完整路径和文件名即可:

<&#63;php
$db = new Database('/path/to/db.sqlite');
&#63;>

登入後複製

整合

为了进行整合,在lib目录下创建Database.php,loadClass()就可以找到它。你的index.php文件现在就会初始化$view和$db并存储到寄存器。你也可以创建__autoload()函数自动加载你所需要的类:

<&#63;php
include 'Zend.php';
function __autoload($class)
{
  Zend::loadClass($class);
}
$db = new Database('/path/to/db.sqlite');
Zend::register('db', $db);
$view = new Zend_View;
$view->setScriptPath('/path/to/views');
Zend::register('view', $view);
$controller = Zend_Controller_Front::getInstance()
       ->setControllerDirectory('/path/to/controllers')
       ->dispatch();
&#63;>

登入後複製

接下来,在views目录创建一些简单的模板。index.php可以用来显示index视图:

<html>
<head>
 <title>News</title>
</head>
<body>
 <h1 id="News">News</h1>
 <&#63;php foreach ($this->news as $entry) { &#63;>
 <p>
  <a href="/view/<&#63;php echo $this->escape($entry['id']); &#63;>">
  <&#63;php echo $this->escape($entry['title']); &#63;>
  </a>
 </p>
 <&#63;php } &#63;>
 <h1 id="Add-News">Add News</h1>
 <form action="/add/news" method="POST">
 <p>Title:<br /><input type="text" name="title" /></p>
 <p>Content:<br /><textarea name="content"></textarea></p>
 <p><input type="submit" value="Add News" /></p>
 </form>
</body>
</html>

登入後複製

view.php模板可以用来显示选定的新闻条目:

<html>
<head>
 <title>
  <&#63;php echo $this->escape($this->news['title']); &#63;>
 </title>
</head>
<body>
 <h1>
  <&#63;php echo $this->escape($this->news['title']); &#63;>
 </h1>
 <p>
  <&#63;php echo $this->escape($this->news['content']); &#63;>
 </p>
 <h1 id="Comments">Comments</h1>
 <&#63;php foreach ($this->comments as $comment) { &#63;>
 <p>
  <&#63;php echo $this->escape($comment['name']); &#63;> writes:
 </p>
 <blockquote>
  <&#63;php echo $this->escape($comment['comment']); &#63;>
 </blockquote>
 <&#63;php } &#63;>
 <h1 id="Add-a-Comment">Add a Comment</h1>
 <form action="/add/comment" method="POST">
 <input type="hidden" name="newsId" 
  value="<&#63;php echo $this->escape($this->id); &#63;>" />
 <p>Name:<br /><input type="text" name="name" /></p>
 <p>Comment:<br /><textarea name="comment"></textarea></p>
 <p><input type="submit" value="Add Comment" /></p>
 </form>
</body>
</html>

登入後複製

最后,admin.php模板可以用来批准新闻条目:

<html>
<head>
 <title>News Admin</title>
</head>
<body>
 <form action="/admin/approve" method="POST">
 <&#63;php foreach ($this->news as $entry) { &#63;>
 <p>
  <input type="checkbox" name="ids[]"
  value="<&#63;php echo $this->escape($entry['id']); &#63;>" />
  <&#63;php echo $this->escape($entry['title']); &#63;>
  <&#63;php echo $this->escape($entry['content']); &#63;>
 </p>
 <&#63;php } &#63;>
 <p>
  Password:<br /><input type="password" name="password" />
 </p>
 <p><input type="submit" value="Approve" /></p>
 </form>
</body>
</html>

登入後複製

提示:为了保持简单,这个表单用密码作为验证机制。

使用到模板的地方,你只需要把注释替换成几行代码。如IndexController.php就变成下面这样:

<&#63;php
class IndexController extends Zend_Controller_Action 
{
  public function indexAction()
  {
    /* List the news. */
    $db = Zend::registry('db');
    $view = Zend::registry('view');
    $view->news = $db->getNews();
    echo $view->render('index.php');
  }
  public function noRouteAction()
  {
    $this->_redirect('/');
  }
}
&#63;>

登入後複製

因为条理比较清楚,这个程序首页的整个业务逻辑只有四行代码。AddController.php更复杂一点,它需要更多的代码:

<&#63;php
class AddController extends Zend_Controller_Action
{
  function indexAction()
  {
    $this->_redirect('/');
  }
  function commentAction()
  {
    /* Add a comment. */
    $filterPost = new Zend_InputFilter($_POST);
    $db = Zend::registry('db');
    $name = $filterPost->getAlpha('name');
    $comment = $filterPost->noTags('comment');
    $newsId = $filterPost->getDigits('newsId');
    $db->addComment($name, $comment, $newsId);
    $this->_redirect("/view/$newsId");
  }
  function newsAction()
  {
    /* Add news. */
    $filterPost = new Zend_InputFilter($_POST);
    $db = Zend::registry('db');
    $title = $filterPost->noTags('title');
    $content = $filterPost->noTags('content');
    $db->addNews($title, $content);
    $this->_redirect('/');
  }
  function __call($action, $arguments)
  {
    $this->_redirect('/');
  }
}
&#63;>

登入後複製

因为用户在提交表单后被重定向,这个controller不需要视图。

在AdminController.php,你要处理显示管理界面和批准新闻两个action:

<&#63;php
class AdminController extends Zend_Controller_Action
{
  function indexAction()
  {
    /* Display admin interface. */
    $db = Zend::registry('db');
    $view = Zend::registry('view');
    $view->news = $db->getNews('NEW');
    echo $view->render('admin.php');
  }
  function approveAction()
  {
    /* Approve news. */
    $filterPost = new Zend_InputFilter($_POST);
    $db = Zend::registry('db');
    if ($filterPost->getRaw('password') == 'mypass') {
      $db->approveNews($filterPost->getRaw('ids'));
      $this->_redirect('/');
    } else {
      echo 'The password is incorrect.';
    }
  }
  function __call($action, $arguments)
  {
    $this->_redirect('/');
  }
}
&#63;>

登入後複製

最后是ViewController.php:

<&#63;php
class ViewController extends Zend_Controller_Action
{
  function indexAction()
  {
    $this->_redirect('/');
  }
  function __call($id, $arguments)
  {
    /* Display news and comments for $id. */
    $id = Zend_Filter::getDigits($id);
    $db = Zend::registry('db');
    $view = Zend::registry('view');
    $view->news = $db->getNews($id);
    $view->comments = $db->getComments($id);
    $view->id = $id;
    echo $view->render('view.php');
  }
}
&#63;>

登入後複製

虽然很简单,但我们还是提供了一个功能较全的新闻和评论程序。最好的地方是由于有较好的设计,增加功能变得很简单。而且随着Zend Framework越来越成熟,只会变得更好。

更多信息

这个教程只是讨论了ZF表面的一些功能,但现在也有一些其它的资源可供参考。在http://framework.zend.com/manual/有手册可以查询,Rob Allen在http://akrabat.com/zend-framework/介绍了一些他使用Zend Framework的经验,而Richard Thomas也在http://www.cyberlot.net/zendframenotes提供了一些有用的笔记。如果你有自己的想法,可以访问Zend Framework的新论坛:http://www.phparch.com/discuss/index.php/f/289//。

结束语

要对预览版进行评价是很容易的事,我在写这个教程时也遇到很多困难。总的来说,我想Zend Framework显示了承诺,加入的每个人都是想继续完善它。

更多关于zend相关内容感兴趣的读者可查看本站专题:《Zend FrameWork框架入门教程》、《php优秀开发框架总结》、《Yii框架入门及常用技巧总结》、《ThinkPHP入门教程》、《php面向对象程序设计入门教程》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

希望本文所述对大家基于Zend Framework框架的PHP程序设计有所帮助。

您可能感兴趣的文章:

  • Zend Framework框架教程之Zend_Db_Table_Rowset用法实例分析
  • Zend Framework教程之Zend_Db_Table_Row用法实例分析
  • Zend Framework教程之Zend_Db_Table用法详解
  • Zend Framework教程之Zend_Form组件实现表单提交并显示错误提示的方法
  • Zend Framework框架Smarty扩展实现方法
  • Zend Framework框架路由机制代码分析
  • Zend Framework实现具有基本功能的留言本(附demo源码下载)
  • Zend Framework实现将session存储在memcache中的方法
  • Zend Framework分页类用法详解
  • Zend Framework实现多文件上传功能实例
  • Zend Framework入门之环境配置及第一个Hello World示例(附demo源码下载)
  • Zend Framework教程之连接数据库并执行增删查的方法(附demo源码下载)
  • Zend Framework教程之Zend_Db_Table表关联实例详解

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/1113710.htmlTechArticleZend Framework开发入门经典教程,zendframework 本文讲述了Zend Framework开发入门相关知识点。分享给大家供大家参考,具体如下: Zend Framework发布...
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

值得你花時間看的擴散模型教程,來自普渡大學 值得你花時間看的擴散模型教程,來自普渡大學 Apr 07, 2024 am 09:01 AM

Diffusion不僅可以更好地模仿,而且可以進行「創作」。擴散模型(DiffusionModel)是一種影像生成模型。與先前AI領域大名鼎鼎的GAN、VAE等演算法,擴散模型另闢蹊徑,其主要想法是先對影像增加噪聲,再逐步去噪的過程。其中如何去噪還原原影像是演算法的核心部分。最終演算法能夠從一張隨機的雜訊影像中產生影像。近年來,生成式AI的驚人成長將文字轉換為圖像生成、視訊生成等領域的許多令人興奮的應用提供了支援。這些生成工具背後的基本原理是擴散的概念,這是一種特殊的取樣機制,克服了先前的方法中被

一鍵生成PPT! Kimi :讓「PPT民工」先浪起來 一鍵生成PPT! Kimi :讓「PPT民工」先浪起來 Aug 01, 2024 pm 03:28 PM

Kimi:一句話,十幾秒鐘,一份PPT就新鮮出爐了。 PPT這玩意兒,可太招人煩了!開個碰頭會,要有PPT;寫個週報,要做PPT;拉個投資,要展示PPT;就連控訴出軌,都得發個PPT。大學比較像是學了個PPT專業,上課看PPT,下課做PPT。或許,37年前丹尼斯・奧斯汀發明PPT時也沒想到,有一天PPT竟然如此氾濫成災。嗎嘍們做PPT的苦逼經歷,說起來都是淚。 「一份二十多頁的PPT花了三個月,改了幾十遍,看到PPT都想吐」;「最巔峰的時候,一天做了五個PPT,連呼吸都是PPT」;「臨時開個會,都要做個

CVPR 2024全部獎項公佈!近萬人線下參會,Google華人研究員獲最佳論文獎 CVPR 2024全部獎項公佈!近萬人線下參會,Google華人研究員獲最佳論文獎 Jun 20, 2024 pm 05:43 PM

北京時間6月20日凌晨,在西雅圖舉辦的國際電腦視覺頂會CVPR2024正式公佈了最佳論文等獎項。今年共有10篇論文獲獎,其中2篇最佳論文,2篇最佳學生論文,另外還有2篇最佳論文提名和4篇最佳學生論文提名。電腦視覺(CV)領域的頂級會議是CVPR,每年都會吸引大量研究機構和高校參會。根據統計,今年共提交了11532份論文,2719篇被接收,錄取率為23.6%。根據佐治亞理工學院對CVPR2024的數據統計分析,從研究主題來看,論文數量最多的是圖像和視頻合成與生成(Imageandvideosyn

入門學習C語言的五款程式設計軟體 入門學習C語言的五款程式設計軟體 Feb 19, 2024 pm 04:51 PM

C語言作為一門廣泛應用的程式語言,對於想從事電腦程式設計的人來說是必學的基礎語言之一。然而,對於初學者來說,學習新的程式語言可能會有些困難,尤其是缺乏相關的學習工具和教材。在本文中,我將介紹五款幫助初學者入門C語言的程式設計軟體,幫助你快速上手。第一款程式軟體是Code::Blocks。 Code::Blocks是一個免費的開源整合開發環境(IDE),適用於

從裸機到700億參數大模型,這裡有一個教程,還有現成可用的腳本 從裸機到700億參數大模型,這裡有一個教程,還有現成可用的腳本 Jul 24, 2024 pm 08:13 PM

我們知道LLM是在大規模電腦叢集上使用海量資料訓練得到的,本站曾介紹過不少用於輔助和改進LLM訓練流程的方法和技術。而今天,我們要分享的是一篇深入技術底層的文章,介紹如何將一堆連作業系統也沒有的「裸機」變成用來訓練LLM的電腦叢集。這篇文章來自於AI新創公司Imbue,該公司致力於透過理解機器的思維方式來實現通用智慧。當然,將一堆連作業系統也沒有的「裸機」變成用於訓練LLM的電腦叢集並不是一個輕鬆的過程,充滿了探索和試錯,但Imbue最終成功訓練了一個700億參數的LLM,並在此過程中積累

PyCharm社群版安裝指南:快速掌握全部步驟 PyCharm社群版安裝指南:快速掌握全部步驟 Jan 27, 2024 am 09:10 AM

快速入門PyCharm社群版:詳細安裝教學全解析導言:PyCharm是一個功能強大的Python整合開發環境(IDE),它提供了一套全面的工具,可以幫助開發人員更有效率地編寫Python程式碼。本文將詳細介紹如何安裝PyCharm社群版,並提供具體的程式碼範例,幫助初學者快速入門。第一步:下載和安裝PyCharm社群版要使用PyCharm,首先需要從其官方網站上下

技術入門者必看:C語言和Python難易度解析 技術入門者必看:C語言和Python難易度解析 Mar 22, 2024 am 10:21 AM

標題:技術入門者必看:C語言和Python難易度解析,需要具體程式碼範例在當今數位化時代,程式設計技術已成為一項越來越重要的能力。無論是想要從事軟體開發、數據分析、人工智慧等領域,還是僅僅出於興趣學習編程,選擇一門合適的程式語言是第一步。而在眾多程式語言中,C語言和Python作為兩種廣泛應用的程式語言,各有其特色。本文將對C語言和Python的難易度進行解析

AI在用 | AI製作獨居女孩生活Vlog,3天狂攬萬點讚量 AI在用 | AI製作獨居女孩生活Vlog,3天狂攬萬點讚量 Aug 07, 2024 pm 10:53 PM

機器之能報道編輯:楊文以大模型、AIGC為代表的人工智慧浪潮已經在悄悄改變我們生活及工作方式,但絕大部分人依然不知道該如何使用。因此,我們推出了「AI在用」專欄,透過直覺、有趣且簡潔的人工智慧使用案例,來具體介紹AI使用方法,並激發大家思考。我們也歡迎讀者投稿親自實踐的創新用例。影片連結:https://mp.weixin.qq.com/s/2hX_i7li3RqdE4u016yGhQ最近,獨居女孩的生活Vlog在小紅書上走紅。一個插畫風格的動畫,再配上幾句治癒系文案,短短幾天就能輕鬆狂攬上

See all articles