<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 教程4: 使用CRUD(Tutorial 4: Working with the CRUD) 后臺通常提供表單來允許用戶提交數據. 繼續對INVO的解釋, 我們現在處理CRUD的創建, 一個非常常見的操作任務, Phalcon將會幫助你使用表單, 校驗, 分頁和更多. 在INVO(公司, 產品和產品類型)中大部分選項操作數據都是使用一個基礎的常見的[CRUD](http://en.wikipedia.org/wiki/Create,_read,_update_and_delete)(創建, 讀取, 更新和刪除)開發的. 每個CRUD包含以下文件: ~~~ invo/ app/ controllers/ ProductsController.php models/ Products.php forms/ ProductsForm.php views/ products/ edit.volt index.volt new.volt search.volt ~~~ 每個控制器都有以下方法: ~~~ <?php class ProductsController extends ControllerBase { /** * 開始操作, 它展示"search"視圖 */ public function indexAction() { // ... } /** * 基于從"index"發送過來的條件處理"search" * 返回一個分頁結果 */ public function searchAction() { // ... } /** * 展示創建一個"new"(新)產品的視圖 */ public function newAction() { // ... } /** * 展示編輯一個已存在"edit"(編輯)產品的視圖 */ public function editAction() { // ... } /** * 基于"new"方法中輸入的數據創建一個產品 */ public function createAction() { // ... } /** * 基于"edit"方法中輸入的數據更新一個產品 */ public function saveAction() { // ... } /** * 刪除一個已存在的產品 */ public function deleteAction($id) { // ... } } ~~~ ## 表單搜索(The Search Form) 每個 CRUD 都開始于一個搜索表單. 這個表單展示了表(products)中的每個字段, 允許用戶為一些字段創建一個搜索條件. 表 “products” 和表 “products\_types” 是關系表. 既然這樣, 我們先前查詢表中的記錄以便于字段的搜索: ~~~ <?php /** * 開始操作, 它展示"search"視圖 */ public function indexAction() { $this->persistent->searchParams = null; $this->view->form = new ProductsForm(); } ~~~ ProductsForm 表單的實例 (app/forms/ProductsForm.php)傳遞給了視圖. 這個表單定義了用戶可見的字段: ~~~ <?php use Phalcon\Forms\Form; use Phalcon\Forms\Element\Text; use Phalcon\Forms\Element\Hidden; use Phalcon\Forms\Element\Select; use Phalcon\Validation\Validator\Email; use Phalcon\Validation\Validator\PresenceOf; use Phalcon\Validation\Validator\Numericality; class ProductsForm extends Form { /** * 初始化產品表單 */ public function initialize($entity = null, $options = []) { if (!isset($options["edit"])) { $element = new Text("id"); $element->setLabel("Id"); $this->add( $element ); } else { $this->add( new Hidden("id") ); } $name = new Text("name"); $name->setLabel("Name"); $name->setFilters( [ "striptags", "string", ] ); $name->addValidators( [ new PresenceOf( [ "message" => "Name is required", ] ) ] ); $this->add($name); $type = new Select( "profilesId", ProductTypes::find(), [ "using" => [ "id", "name", ], "useEmpty" => true, "emptyText" => "...", "emptyValue" => "", ] ); $this->add($type); $price = new Text("price"); $price->setLabel("Price"); $price->setFilters( [ "float", ] ); $price->addValidators( [ new PresenceOf( [ "message" => "Price is required", ] ), new Numericality( [ "message" => "Price is required", ] ), ] ); $this->add($price); } } ~~~ 表單是使用面向對象的方式聲明的, 基于[forms](http://docs.iphalcon.cn/reference/forms.html)組件提供的元素. 每個元素都遵循近乎相同的結構: ~~~ <?php // 創建一個元素 $name = new Text("name"); // 設置它的label $name->setLabel("Name"); // 在驗證元素之前應用這些過濾器 $name->setFilters( [ "striptags", "string", ] ); // 應用此驗證 $name->addValidators( [ new PresenceOf( [ "message" => "Name is required", ] ) ] ); // 增加元素到表單 $this->add($name); ~~~ 在表單中其它元素也是這樣使用: ~~~ <?php // 增加一個隱藏input到表單 $this->add( new Hidden("id") ); // ... $productTypes = ProductTypes::find(); // 增加一個HTML Select (列表) 到表單 // 數據從"product_types"中填充 $type = new Select( "profilesId", $productTypes, [ "using" => [ "id", "name", ], "useEmpty" => true, "emptyText" => "...", "emptyValue" => "", ] ); ~~~ 注意,`ProductTypes::find()`包含的必須的數據 使用`Phalcon\Tag::select()`來填充 SELECT 標簽. 一旦表單傳遞給視圖, 它會進行渲染并呈現給用戶: ~~~ {{ form("products/search") }} <h2> Search products </h2> <fieldset> {% for element in form %} <div class="control-group"> {{ element.label(["class": "control-label"]) }} <div class="controls"> {{ element }} </div> </div> {% endfor %} <div class="control-group"> {{ submit_button("Search", "class": "btn btn-primary") }} </div> </fieldset> {{ endForm() }} ~~~ 這會生成下面的HTML: ~~~ <form action="/invo/products/search" method="post"> <h2> Search products </h2> <fieldset> <div class="control-group"> <label for="id" class="control-label">Id</label> <div class="controls"> <input type="text" id="id" name="id" /> </div> </div> <div class="control-group"> <label for="name" class="control-label">Name</label> <div class="controls"> <input type="text" id="name" name="name" /> </div> </div> <div class="control-group"> <label for="profilesId" class="control-label">profilesId</label> <div class="controls"> <select id="profilesId" name="profilesId"> <option value="">...</option> <option value="1">Vegetables</option> <option value="2">Fruits</option> </select> </div> </div> <div class="control-group"> <label for="price" class="control-label">Price</label> <div class="controls"> <input type="text" id="price" name="price" /> </div> </div> <div class="control-group"> <input type="submit" value="Search" class="btn btn-primary" /> </div> </fieldset> </form> ~~~ 當表單提交的時候, 控制器里面的”search”操作是基于用戶輸入的數據執行搜索的. ## 執行搜索(Performing a Search) “search”操作有兩個行為. 當通過POST訪問, 它基于表單發送的數據執行搜索, 但是當通過GET訪問它會在分頁中移動當前的頁數. 為了區分HTTP方法,我們使用[Request](http://docs.iphalcon.cn/reference/request.html)組件進行校驗: ~~~ <?php /** * 基于從"index"發送過來的條件處理"search" * 返回一個分頁結果 */ public function searchAction() { if ($this->request->isPost()) { // 創建查詢條件 } else { // 使用已存在的條件分頁 } // ... } ~~~ 在[Phalcon\\Mvc\\Model\\Criteria](http://docs.iphalcon.cn/api/Phalcon_Mvc_Model_Criteria.html)的幫助下, 我們基于從表單發送來的數據類型和值創建智能的搜索條件: ~~~ <?php $query = Criteria::fromInput( $this->di, "Products", $this->request->getPost() ); ~~~ 這個方法驗證值 “” (空字符串) 和值 null 的區別并考慮到這些來創建搜索條件: * 如果字段日期類型是text或者類似的(char, varchar, text, 等等) 它會使用一個SQL “like” 操作符來過濾結果. * 如果日期類型不是text或者類似的, 它將會使用操作符”=”. 另外, “Criteria” 會忽略`$_POST`所有不與表中的任何字段相匹配的變量. 值會自動避免使用”參數綁定”. 現在, 我們在控制器的會話袋里存儲產品參數: ~~~ <?php $this->persistent->searchParams = $query->getParams(); ~~~ 會話袋在控制器里面是一個特殊的屬性, 在使用 session 服務的不同請求之間依然存在. 當訪問的時候, 這個屬性會注入一個[Phalcon\\Session\\Bag](http://docs.iphalcon.cn/api/Phalcon_Session_Bag.html)實例, 對于每個控制器來說, 這是獨立的. 然后, 基于內置的參數我們執行查詢: ~~~ <?php $products = Products::find($parameters); if (count($products) === 0) { $this->flash->notice( "The search did not found any products" ); return $this->dispatcher->forward( [ "controller" => "products", "action" => "index", ] ); } ~~~ 如果搜索不返回一些產品, 我們再一次轉發用戶到 index 方法. 讓我們模擬搜索返回結果, 然后我們創建一個分頁來輕松的瀏覽他們: ~~~ <?php use Phalcon\Paginator\Adapter\Model as Paginator; // ... $paginator = new Paginator( [ "data" => $products, // 分頁的數據 "limit" => 5, // 每頁的行數 "page" => $numberPage, // 查看的指定頁 ] ); // 獲取分頁中當前頁面 $page = $paginator->getPaginate(); ~~~ 最后我們通過返回的頁面來瀏覽: ~~~ <?php $this->view->page = $page; ~~~ 在視圖里面 (app/views/products/search.volt), 我們在當前頁面循環相應的結果, 在當前頁面給用戶展示每一行記錄: ~~~ {% for product in page.items %} {% if loop.first %} <table> <thead> <tr> <th>Id</th> <th>Product Type</th> <th>Name</th> <th>Price</th> <th>Active</th> </tr> </thead> <tbody> {% endif %} <tr> <td> {{ product.id }} </td> <td> {{ product.getProductTypes().name }} </td> <td> {{ product.name }} </td> <td> {{ "%.2f"|format(product.price) }} </td> <td> {{ product.getActiveDetail() }} </td> <td width="7%"> {{ link_to("products/edit/" ~ product.id, "Edit") }} </td> <td width="7%"> {{ link_to("products/delete/" ~ product.id, "Delete") }} </td> </tr> {% if loop.last %} </tbody> <tbody> <tr> <td colspan="7"> <div> {{ link_to("products/search", "First") }} {{ link_to("products/search?page=" ~ page.before, "Previous") }} {{ link_to("products/search?page=" ~ page.next, "Next") }} {{ link_to("products/search?page=" ~ page.last, "Last") }} <span class="help-inline">{{ page.current }} of {{ page.total_pages }}</span> </div> </td> </tr> </tbody> </table> {% endif %} {% else %} No products are recorded {% endfor %} ~~~ 在上面的例子中有很多東西值得詳細介紹. 首先, 當前頁面的記錄是使用 Volt 的 ‘for’ 循環出來的. Volt 對 PHP 的 ‘foreach’ 提供了一個簡單的語法. ~~~ {% for product in page.items %} ~~~ 對于 PHP 來說也是一樣: ~~~ <?php foreach ($page->items as $product) { ?> ~~~ 完整的 ‘for’ 提供了以下: ~~~ {% for product in page.items %} {% if loop.first %} Executed before the first product in the loop {% endif %} Executed for every product of page.items {% if loop.last %} Executed after the last product is loop {% endif %} {% else %} Executed if page.items does not have any products {% endfor %} ~~~ 現在你可以返回到頁面找出每個塊都在做什么. 在”product”中的每個字段都有相應的輸出: ~~~ <tr> <td> {{ product.id }} </td> <td> {{ product.productTypes.name }} </td> <td> {{ product.name }} </td> <td> {{ "%.2f"|format(product.price) }} </td> <td> {{ product.getActiveDetail() }} </td> <td width="7%"> {{ link_to("products/edit/" ~ product.id, "Edit") }} </td> <td width="7%"> {{ link_to("products/delete/" ~ product.id, "Delete") }} </td> </tr> ~~~ 正如我們看到的, 在之前使用`product.id`和在PHP中使用`$product->id`是等價的, we made the same with`product.name`and so on. 其它字段都表現的有些不同, 例如, 讓我們看下`product.productTypes.name`. 要理解這部分, 我們必須看一下 Products 模型 (app/models/Products.php): ~~~ <?php use Phalcon\Mvc\Model; /** * 產品 */ class Products extends Model { // ... /** * 產品初始化 */ public function initialize() { $this->belongsTo( "product_types_id", "ProductTypes", "id", [ "reusable" => true, ] ); } // ... } ~~~ 一個模型有一個名為`initialize()`的方法, 這個方法在每次請求的時候調用一次兵器它服務ORM去初始化一個模型. 在這種情況話, “Products” 通過定義這個模型跟另外一個叫做 “ProductTypes” 的模型有一對多的關系從而初始化. ~~~ <?php $this->belongsTo( "product_types_id", "ProductTypes", "id", [ "reusable" => true, ] ); ~~~ 它的意思是, “Products” 的本地屬性”product\_types\_id” 跟 “ProductTypes” 模型里面的屬性 “id” 是一對多的關系. 通過定義這個關系我們可以通過如下方法來訪問產品類型的名字: ~~~ <td>{{ product.productTypes.name }}</td> ~~~ 字段 “price” 使用一個 Volt 過濾器來格式化輸出: ~~~ <td>{{ "%.2f"|format(product.price) }}</td> ~~~ 在原生PHP中, 它將是這樣的: ~~~ <?php echo sprintf("%.2f", $product->price) ?> ~~~ 使用模型中已經實現的幫助者函數來輸出產品是否是有效的: ~~~ <td>{{ product.getActiveDetail() }}</td> ~~~ 這個方法在模型中定義了. ## 創建和更新記錄(Creating and Updating Records) 現在, 讓我們看看 CRUD 如何創建和更新記錄. 從 “new” 和 “edit” 視圖, 通過用戶輸入的數據發送 “create” 和 “save” 方法從而分別執行 “creating” 和 “updating” 產品的方法. 在創建的情況下, 我們提取提交的數據然后分配它們到一個新的 “Products” 實例: ~~~ <?php /** * 基于在 "new" 方法中輸入的數據創建一個產品 */ public function createAction() { if (!$this->request->isPost()) { return $this->dispatcher->forward( [ "controller" => "products", "action" => "index", ] ); } $form = new ProductsForm(); $product = new Products(); $product->id = $this->request->getPost("id", "int"); $product->product_types_id = $this->request->getPost("product_types_id", "int"); $product->name = $this->request->getPost("name", "striptags"); $product->price = $this->request->getPost("price", "double"); $product->active = $this->request->getPost("active"); // ... } ~~~ 還記得我們在產品表單中定義的過濾器嗎? 數據在開始分配到`$product`對象前進行過濾. 這個過濾器是可選的; ORM同樣也會轉義輸入的數據和根據列類型執行附加的轉換: ~~~ <?php // ... $name = new Text("name"); $name->setLabel("Name"); // 過濾 name $name->setFilters( [ "striptags", "string", ] ); // 驗證 name $name->addValidators( [ new PresenceOf( [ "message" => "Name is required", ] ) ] ); $this->add($name); ~~~ 當保存的時候, 我們就會知道 ProductsForm (app/forms/ProductsForm.php) 表單提交的數據是否否則業務規則和實現的驗證: ~~~ <?php // ... $form = new ProductsForm(); $product = new Products(); // V驗證輸入 $data = $this->request->getPost(); if (!$form->isValid($data, $product)) { $messages = $form->getMessages(); foreach ($messages as $message) { $this->flash->error($message); } return $this->dispatcher->forward( [ "controller" => "products", "action" => "new", ] ); } ~~~ 最后, 如果表單沒有返回任何驗證消息, 我們就可以保存產品實例了: ~~~ <?php // ... if ($product->save() === false) { $messages = $product->getMessages(); foreach ($messages as $message) { $this->flash->error($message); } return $this->dispatcher->forward( [ "controller" => "products", "action" => "new", ] ); } $form->clear(); $this->flash->success( "Product was created successfully" ); return $this->dispatcher->forward( [ "controller" => "products", "action" => "index", ] ); ~~~ 現在, 在更新產品的情況下, 我們必須先將當前編輯的記錄展示給用戶: ~~~ <?php /** * 基于它的id編輯一個產品 */ public function editAction($id) { if (!$this->request->isPost()) { $product = Products::findFirstById($id); if (!$product) { $this->flash->error( "Product was not found" ); return $this->dispatcher->forward( [ "controller" => "products", "action" => "index", ] ); } $this->view->form = new ProductsForm( $product, [ "edit" => true, ] ); } } ~~~ 通過將模型作為第一個參數傳遞過去找出被綁定到表單的數據. 多虧了這個, 用戶可以改變任何值, 然后通過 “save” 方法發送它到數據庫: ~~~ <?php /** * 在 "edit"方法中基于輸入的數據更新一個產品 */ public function saveAction() { if (!$this->request->isPost()) { return $this->dispatcher->forward( [ "controller" => "products", "action" => "index", ] ); } $id = $this->request->getPost("id", "int"); $product = Products::findFirstById($id); if (!$product) { $this->flash->error( "Product does not exist" ); return $this->dispatcher->forward( [ "controller" => "products", "action" => "index", ] ); } $form = new ProductsForm(); $data = $this->request->getPost(); if (!$form->isValid($data, $product)) { $messages = $form->getMessages(); foreach ($messages as $message) { $this->flash->error($message); } return $this->dispatcher->forward( [ "controller" => "products", "action" => "new", ] ); } if ($product->save() === false) { $messages = $product->getMessages(); foreach ($messages as $message) { $this->flash->error($message); } return $this->dispatcher->forward( [ "controller" => "products", "action" => "new", ] ); } $form->clear(); $this->flash->success( "Product was updated successfully" ); return $this->dispatcher->forward( [ "controller" => "products", "action" => "index", ] ); } ~~~ 我們已經看到 Phalcon 如何以一種結構化的方式讓你創建表單和從一個數據庫中綁定數據. 在下一章, 我們將會看到如何添加自定義 HTML 元素, 比如一個菜單.
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看