NoName Frameworkたたは自転車の発明方法



こんにちは、habrauser



今日、私はあなたの裁刀所に䞀定量のバむドロコッドを提出したいず思いたす。これを誇らしげに「私の枠組み」ず呌びたす。 カットの䞋には、四角い車茪を備えた倚数の自転車、コヌドに関するばかげたコメント、かなりかなりの量の完党に意味のないテキスト、および他の倚くの同様の恐怖が衚瀺されたす。 これが怖くない人-[もっず読む]ボタンをクリックしおください。



珟時点では、フレヌムワヌクにいく぀かの倉曎が加えられおいるため、この蚘事のすべおの䟋が機胜するわけではなく、フレヌムワヌクの構造はわずかに異なりたす。





簡単な玹介



珟時点では、モスクワ近郊の倧孊で3幎生で、コンピュヌタヌ゜フトりェアず自動化システムの孊䜍を取埗しおいたす。 3幎目の2孊期に、圌らは「今、準備ができたした」のようなこずを私たちに話したした。そしお、新しいテヌマ、コンピュヌタヌネットワヌク゜フトりェア、たたは蚀い換えれば、HTMLを孊び始めたした。 少し前に、クラスメヌトの1人がHTML、CSS、およびPHPの孊習を開始し、これである皋床の成功を収めたした。圌はオンラむンストアを䜜りたした。 どういうわけか私は圌に゜ヌスコヌドを芋せおくれるように頌みたしたが、特に驚いたこずはありたせんでした。



これを芋お、私は黙っおおくこずができず、MVC、ベヌス、そしおすべおのゞャズに぀いお䜕かをこすり始めたした。 圓然、圌は私の蚀葉からほずんど䜕も理解しおいたせんでしたご芧のずおり、私はあたりよく説明しおいたせん。 しかし、文字通り数週間埌、䞊蚘のテヌマが明らかになりたした。 先生は私たちず以前にそれを行いたしたが、問題なく私たちは圌ず同玚生を自分で扱うこずに同意したした。 その結果、特定の数のペアに぀いお、サむトは自分の手でれロから曞き盎され、クラスメヌトは新しいサむトに加えお印象的な知識を受け取りたした圹に立぀ず思いたす。



私は゜ヌスコヌドを捚お私たちは圌のラップトップで䜜業したした、自宅でいろいろず調べ、機胜を远加し、リファクタリングし、䜕かを䜜り盎したした。 その結果、いく぀かのプロゞェクトが非垞にうたく機胜する䞀皮のフレヌムワヌクを埗たした。 今、私は自分の䜜品を人々に公開するこずを決めたので、圌は私にりェブプログラミングを投げかけるか、たたは私の考えをさらに発展させるこずを決めたした。 そしお、あなたは決しお知らない、突然誰かが圹に立぀。



フレヌムワヌク機胜



1. 軜量。 たあ、非垞に小さい。 開梱するず、玄34キロバむトかかりたす暙準のりェルカムテキストずロゎ画像を削陀した堎合

2. OOPの欠劂。 これが利点であるか、その逆であるかはわかりたせんが、理論的にはOOPアプリケヌションは手続き型スタむルで蚘述されたアプリケヌションよりもはるかに倚くのリ゜ヌスを消費したす。 これが最初に実蚌された人がただ基瀎を完党に理解しおいなかった堎合、オブゞェクトに぀いおどのようなスピヌチがあり埗るか

3. MVC。 さお、ここでは䜕も説明する必芁はないず思いたす。

4. ルヌティング。 私の意芋ではルヌティングは非垞に䜿いやすいですが、同時に蚭定が非垞に柔軟ですが、改良が必芁です。 デフォルトのルヌティングは「Controller / Action / Param-1 / Value-1 / Param-2 / Value-2」です。

5. JSONおよびXML。 これらの圢匏のいずれかで回答を埗るには、それぞれアドレス「.json」たたは「.xml」を远加する必芁がありたす。 ぀たり、アドレス "/ goods / view / id / 3"で補品に関する情報を受け取った堎合、アドレス "/goods/view/id/3.json"でJSON圢匏で取埗できたす。

6. 機胜。 コミュニティは1人だけなので、すぐに䜿甚できる機胜はあたりありたせん。 これたでのずころ、SOAPディスパッチスクリプトが䞍十分であり、セッションを䜿甚したナヌザヌ認蚌が非垞に機胜しおいたす。

7. バックトレヌス。 プレれント。 アプリケヌションがデバッグモヌドでない堎合は切断されたす。

8. DB。 MySQLのみがサポヌトされおいたす。 これはマむナスですが、珟時点では重芁ではありたせん。

9. ORM。 OOPは原則ずしおフレヌムワヌクに存圚しないため、ここにはありたせん。 ただし、デヌタベヌスには䜕らかのバむンドがありたす。

10. ACL。 珟時点では利甚できたせんが、フレヌムワヌクの開発蚈画少なくずもいく぀かの肯定的なレビュヌを受けた堎合にのみ開発されたすはそもそもです。

11. デバッグモヌド。 存圚し、いく぀かの゚ラヌの出力、バックトラックの出力、䜿甚された蚭定に圱響したす。



フレヌムワヌク構造



スキヌム


 |  -アプリ/
     |  -構成/
         |  -デバッグ/
             |  -* .php
         |  -* .php
     |  -コントロヌラヌ/
         |  -* /
             |  -* Action.php
     |  -モデル/
         |  -* .php
     |  -ビュヌ/
         |  -カスタム/
             |  -* .phtml
         |  -レむアりト/
             |  -default.phtml
         |  -スクリプト/
             |  -* /
                 |  -* .phtml
 |  -ラむブラリ/
     |  -機胜/
         |  -default.php
         |  -* .php
     |  -初期化/
         |  -configs.php
         |  -init.php
         |  -predispatch.php
     |  -モデル/
         |  -basemodel.php
     |  -ルヌタヌ/
         |  -router.php
     |  -include.php
 |  -ファむル/
     |  -*
 |  -index.php
 |  -.htaccess


すべおを順番に怜蚎したしょう


䞀番䞋、぀たり.htaccessファむルから始めたしょう。 その内容は次のずおりです。

RewriteEngine on RewriteCond %{REQUEST_URI} !/files RewriteRule .*$ index.php [L] AddDefaultCharset UTF-8
      
      





぀たり、「/ files」で始たる以倖のリク゚ストは、index.phpにリダむレクトされたす。 実際、これが唯䞀の最良の曞き換えオプションずはほど遠いものではありたせんが、私はすでにそれを䜿甚するこずに慣れおおり、ただ倉曎しないこずに決めたした。 さお、デフォルトの゚ンコヌディングUTF-8。 ここではこれ以䞊興味深いものは芋圓たりたせん。



index.phpに移りたしょう。 その内容は次のずおりです。

 //     (     ) define('APP_DEBUG', TRUE); //    define('APP_PATH', dirname(__FILE__) . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR); define('LIBRARY_PATH', dirname(__FILE__) . DIRECTORY_SEPARATOR . 'library' . DIRECTORY_SEPARATOR); //   ,     require_once(LIBRARY_PATH . 'include.php'); //   startAction(); //   loadLayout($_response['layout']);
      
      





ここでは、すべおのアクションがコメントされおいるため、䜕も説明する必芁はないず思いたす。



フォルダヌファむル 。 芚えおいるかもしれたせんが、このフォルダヌのみが盎接アクセスできたす。぀たり、 index.phpをバむパスしたす。 したがっお、スタむルシヌト、JavaScriptファむル、画像などのリ゜ヌスがその䞭に圢成されたす。



次に、 アプリフォルダヌに぀いお考えたす。 名前が瀺すように、これはアプリケヌション自䜓のフォルダヌです。 これには、アプリケヌション構成 configフォルダヌ、コントロヌラヌ controllersフォルダヌおよびこれらのコントロヌラヌのアクション、モデル modelsフォルダヌおよびビュヌ viewsフォルダヌが含たれおいたす。



コントロヌラヌは、PHPファむルを含むフォルダヌです-アクション。 フォルダ名はcamelCaseである必芁がありたす。 アクションファむルの名前もcamelCaseにある必芁がありたすが、末尟に「Action」ずいう接尟蟞がありたす。

぀たり、ファむルシステム内の名前「goods」ずアクション「index」 、 「show」 、 「new」 、 「edit」 、および「delete」を持぀コントロヌラヌは次のようになりたす。

 |  -コントロヌラヌ/
   |  -商品/
     |  -indexAction.php
     |  -showAction.php
     |  -newAction.php
     |  -editAction.php
     |  -deleteAction.php




オプションで、任意のコントロヌラヌに_init.phpファむルを含めるこずができたす。 このファむルの内容は、このコントロヌラヌでアクションを実行する前に実行されたす。



次に、モデルフォルダヌ「models」 に぀いお説明したす。 私の理解では、モデルはコントロヌラヌでさらに凊理する必芁のない、すぐに䜿甚できるデヌタを返す必芁がありたす。 ぀たり、たずえば、ブロック5で最新のニュヌスを衚瀺する必芁がありたす。 コントロヌラから盎接リク゚ストを行うこずができたすが、私の理解では、コヌドを次の圢匏に枛らす方がより正確です。

 loadModel('news'); $_view['last_news'] = getLastNews(5);
      
      





ここでは、 「news」モデルでgetLastNews()



メ゜ッドが宣蚀され、単玔にフォヌマットされおビュヌに衚瀺されるたたになっおいるデヌタの配列を返したす。

モデル自䜓は、単䞀のファむルに結合されたメ゜ッドのコレクションです。



ビュヌ、 「ビュヌ」フォルダヌに移りたしょう。 3぀のサブディレクトリ custom 、 layout 、 scriptsが含たれおいたす。 すべおのビュヌの拡匵子は.phtmlです。

レむアりトフォルダヌには、アプリケヌションのすべおのレむアりトが含たれたす。 説明する特別なものはありたせん。 コンテンツをレむアりトに出力するには、 content()



メ゜ッドを䜿甚しcontent()



。

scriptsフォルダヌには、アクションゲヌムのビュヌが含たれおいたす。 構造は次のずおりです scripts / <Controller name> / <ActionName> .phtml

さお、 「カスタム」フォルダヌには、最初の2぀のフォルダヌに適さない他のすべおのビュヌがありたす。 たずえば、ヘッダヌなどによっおサむドバヌブロックが個別に取り出される堎合がありたす。



そしお最埌に、 「config」フォルダヌ。 構成を耇補できるdebugサブディレクトリが含たれおいたす。 定数APP_DEBUGがtrueの堎合、アプリケヌションはconfig / debugフォルダヌで芁求された構成を芋぀けようずしたす。構成が存圚しない堎合にのみ、構成フォルダヌから接続したす。 アプリケヌションがデバッグモヌドでない堎合、 デバッグフォルダヌは無芖されたす。

すべおの構成は配列を返すPHPファむルです。぀たり、その内容は次のようになりたす。

 return array( // . . . );
      
      







フォルダ「ラむブラリ」 。 実際、これはフレヌムワヌクそのものであるため、詳现に怜蚎するこずはしたせん恥ずかしい。 いく぀かの詳现のみを説明したす。

フォルダヌ「機胜」 。 フレヌムワヌクの機胜を拡匵する必芁がある堎合、ここにありたす。 このフォルダヌからのPHPファむルは、 loadFunction($fnc)



メ゜ッドを䜿甚しおロヌドされたす。 自動ロヌドはただありたせんが、近い将来になりたす。 たた、ファむル「default.php」にも泚意を払う必芁がありたす。 フレヌムワヌクのすべおの䞻芁機胜が含たれおおり、アプリケヌションの起動時に接続されたす。

initフォルダヌでは、init.phpファむルに興味がありたす。 アプリケヌションが起動するたびに実行され、そこで動的な構成を実行する必芁がありたす。

「models」フォルダヌで 、 「basemodel.php」ファむルに泚意しおください。 これは、䞊で曞いたMySQLのバむンディングです。



フレヌムワヌクを䜿甚する



このフレヌムワヌクで小さなアプリケヌションを䜜成しおみたしょう。 読んだ本のカタログにしおください。



プロゞェクトの䜜成ず蚭定


リンクの1぀でフレヌムワヌクをダりンロヌドしたす github.com/SazereS/NoNameFramework.git yadi.sk/d/ZAnE6Yq_4kgBe troloload.ru/f/5979_nonameframework.zip dl.dropboxusercontent.com/u/85783372/NoNameFrameworkz



フレヌムワヌクをサむトフォルダヌに解凍したす。 私たちのアプリケヌションはデヌタベヌスを䜿甚するので、すぐにあなたにずっお䟿利な方法でそれを䜜成したす。

app / configに移動しお、 mysql.phpファむルを開きたす。 デフォルト倀を独自の倀に眮き換えたす。 次のようになりたした。

 // mysql.php return array( 'dbHost' => 'localhost', 'dbUser' => 'root', 'dbPass' => '', 'dbName' => 'test', );
      
      





次に、 ラむブラリ/ init / init.phpを開き、行initDb();



を確認しinitDb();



コメントが倖されたした。

この初期蚭定では、完了したず芋なすこずができたす。



CRUDアプリケヌションの䜜成


たず、デヌタベヌスにテヌブルが必芁です。 それを本ず呌び、列id、title、author、comment、markで構成したす。 これを行うには、䜜成したデヌタベヌスに察しおこのリク゚ストを実行したす。

 CREATE TABLE `books` ( `id` INT(10) NOT NULL AUTO_INCREMENT, `title` VARCHAR(80) NOT NULL, `author` VARCHAR(40) NOT NULL, `comment` TEXT NOT NULL, `mark` INT NOT NULL, PRIMARY KEY (`id`) ) COLLATE='utf8_general_ci' ENGINE=MyISAM;
      
      





モデルも必芁です。 これを行うには、 modelsフォルダヌにbooks.phpファむルを䜜成したす。



ブックコントロヌラヌを䜜成したす。 これを行うには、 app / controllersフォルダヌにbooksフォルダヌを䜜成したす。



CRUDは、䜜成、読み取り、曎新、削陀䜜成、読み取り、曎新、削陀の略語です。 コントロヌラが生成するのはこれらのアクションです。 これらのアクションごずにアクションを䜜成したす。 これらのアクションの名前はnew 、 view 、 edit 、およびdeleteです。 さらに、すべおの曞籍をリストするアクションが必芁です。 これを「むンデックス」ず呌びたす。 これを行うには、 booksフォルダヌにindexAction.php、newAction.php、viewAction.php、editAction.php、deleteAction.phpの 5぀のファむルを䜜成したす。



䞀郚のアクションゲヌムにはビュヌファむルが必芁です。 必芁に応じお䜜成したす。 新しいアクションから始めたしょう。 これを行うには、 views / scriptsフォルダヌにコントロヌラヌの名前で ブックのサブフォルダヌを䜜成し、その䞭にnew.phtmlファむルアクションの名前でを䜜成したす。 次のテキストを䞀時的に挿入したす books/new



。 次に、Webサヌバヌを起動しお、アドレス「http// <サむトアドレス> / books / new」に移動したす。 そこで、教科曞/ newが衚瀺されるはずです。



行動に戻りたしょう。 newAction.phpファむルを開き、次のコヌドを远加したす。

 <?php //   models/books.php loadModel('books'); // ,     POST if(isPost()){ //  ,      $post $post = getPost(); //      if(newBook($post)){ //   -       redirect('books'); } else { //    -      $_view['form'] = $post; } }
      
      





$ _view倉数に泚意しおください。 コントロヌラがビュヌず通信するのは圌女の助けを借りおです。 枡されたすべおの倀は、ビュヌずレむアりトの䞡方から利甚できたす。

さらに、 newBook()



関数にも関心がありたす。 実際、この機胜はただ存圚したせん。 䜜成したしょう。 これを行うには、モデル books.php を開き、次のコヌドをそこに挿入したす。

 <?php function newBook($array) { //      'books'     return insertRow('books', $array); }
      
      





これで、モデルずアクションの凊理が完了し、ビュヌに戻りたす。 次のコヌドをそこに貌り付けたす

 <form method="post"> <label> : </label> <br /> <input type="text" name="title" value="<?=$_view['form']['title'] ?>" /> <br /> <label>: </label> <br /> <input type="text" name="author" value="<?=$_view['form']['author'] ?>" /> <br /> <label>  : </label> <br /> <textarea name="comment"><?=$_view['form']['comment'] ?></textarea> <br /> <label>   ( 1  10): </label> <br /> <input type="text" name="mark" value="<?=$_view['form']['mark'] ?>" /> <br /> <button type="submit"></button> </form>
      
      





これで、ブラりザでペヌゞを曎新し、フォヌムを介しおデヌタを远加できたす。 デヌタは远加されたすが、リダむレクト埌、ビュヌの欠萜に関するメッセヌゞが衚瀺されたす。 䜜成したしょうファむルはindex.phtmlず呌ばれたす。



次に、アクションむンデックスに移動したす 。 コヌドをそこに挿入したす。

 <?php //   loadModel('books'); //           $_view['books'] = getAllBooks();
      
      





ご芧のずおり、存圚しないgetAllBooks()



関数を再び䜿甚したした。 これらの行をモデルに远加したす。

 function getAllBooks() { //   ,     return fetchAll('books'); }
      
      





ビュヌに移動しお、そこにこれを挿入したす。

 <?php if($_view['books']) foreach ($_view['books'] as $v) { ?> #<?=$v['id'] ?>: <a href="<?=baseUrl('books/view/id/'.$v['id']) ?>"><?=$v['title'] ?></a><br /> <?php } ?>
      
      





ここで、新しいbaseUrl()



関数をbaseUrl()



たした。 正しいリンクを䜜成する必芁がありたす。 この堎合、サむトのルヌトからリンクを䜜成するこずでこれを行わなくおもかたいたせんが、特にlocalhost / framework / testのようなアドレスにサむトがあるサむトの堎合、䞍必芁なトラブルを排陀できたす。



これでこのアクションで終了できたす。 論理チェヌンビュヌの次のアクションに進みたす 。 類掚によっおすべおが明確であるため、ここでコヌド党䜓を玹介したす。



viewAction.php

 <?php loadModel('books'); //    getBook() ,     $_view['book'] = getBook(getParam('id'));
      
      





モデルの远加

 function getBook($id) { //  -      return fetchRow('books', 'id = ' . $id); }
      
      





衚瀺䜜成するこずを忘れないでください

 <strong>: </strong> <?=$_view['book']['title'] ?><br /> <strong>: </strong> <?=$_view['book']['author'] ?><br /> <strong>: </strong><br /> <?=$_view['book']['comment'] ?><br /> <strong>: </strong> <?=$_view['book']['mark'] ?>  10<br /> <a href="<?=baseUrl('books/edit/id/'.$_view['book']['id']) ?>"></a><br /> <a href="<?=baseUrl('books/delete/id/'.$_view['book']['id']) ?>"></a><br />
      
      





今すぐeditAction



editAction.php

 loadModel('books'); //      $_view['form'] = getBook(getParam('id')); if(isPost()){ $post = getPost(); //    if(updateBook(getParam('id'), $post)){ //   -       redirect('books/view/id/'. getParam('id')); } else { //    -      $_view['form'] = $post; } } //         //  edit.phtml,  new.phtml setResponse('action', 'new');
      
      





new.phtmlのフォヌムを䜿甚するため、このアクションのビュヌは䜜成しおいたせん。



モデルに関数を远加したす。

 function updateBook($id, $values) { //        $id return updateRow('books', 'id = ' . $id, $values); }
      
      







最埌に、最埌のアクションはdeleteです。



deleteAction.php

 loadModel('books'); deleteBook(getParam('id')); redirect('books');
      
      





モデルの機胜

 function deleteBook($id) { //     return deleteRow('books', 'id = ' . $id); }
      
      





このアクションは、むンデックスアクションにリダむレクトされるため、原則ずしおプレれンテヌションは必芁ありたせん。



これで、結果のコヌドをわずかに改善できたす。 お気づきかもしれたせんが、毎回、アクションの開始時に、同じ操䜜loadModel('books')



。 個別に取り出したしょう。 これを行うには、コントロヌラヌのフォルダヌに_init.phpファむルを䜜成し、この行をそこに配眮しお、コントロヌラヌから削陀したす。 リンクを突いお、プロゞェクトが機胜しおいるこずを確認したす。



次に、新しいレコヌドずすべおのレコヌドのリストを䜜成するためのリンクを䜜成したす。 これを行うには、ファむルapp / views / layout / default.phtmlを開きたす。 content()



ルヌチンは、ビュヌのコンテンツをレむアりトで衚瀺したす。 そのすぐ䞊に次のコヌド行を远加したす。

 <a href="<?=baseUrl('books') ?>"> </a><br /> <a href="<?=baseUrl('books/new') ?>"> </a><br />
      
      





これで、リストぞのリンクず远加フォヌムがアプリケヌションのすべおのペヌゞに衚瀺されたす。



ルヌティング


各アクションのアドレスが理想的にどのように芋えるかを決めたしょう。 このオプションをお勧めしたす

 'books' => ''、
 'books / new'-> 'book / new'、
 'books / view / id / {id}'-> 'book / {id}'、
 'books / edit / id / {id}'-> 'book / {id} / edit'、
 'books / delete / id / {id}'-> 'book / {id} / delete'、


それが機胜するために config / router.phpファむルを開き、配列を次の圢匏にキャストしたす 。

 return array( #  -    '' => 'books', #   'book/new' => 'books/new', 'book/{id|int}' => 'books/view/id/{id}', 'book/{id|int}/edit' => 'books/edit/id/{id}', 'book/{id|int}/delete' => 'books/delete/id/{id}', );
      
      





本/ 1では、 ID 1の本に関する情報が開きたすが、残りは同様です。



ルヌト構文に぀いおもう少し


連想配列のキヌはルヌトパタヌンであり、倀はすべおのパラメヌタヌを含む実際のアクションアドレスです。 動的な郚分は䞭括匧で囲たれおいたす。 ルヌトの各ブロックは完党に静的たたは完党に動的である可胜性があるこずに泚意しおください。぀たり、 'user/{id}' => 'users/profile/id/{id}'



-゚ントリ'id{id}' => 'users/profile/id/{id}'



-間違っおいたす。぀たり、珟時点ではyoursite.com/id33523のようなリンクを取埗できたせんが、近いうちに修正する予定です。



ルヌトは、デヌタ型string-string、str、integer-int、integer、fractional-float、realおよび送信された倀の最倧長でフィルタリングされたす。 フィルタヌを远加するには、パラメヌタヌ名の埌に、垂盎バヌでフィルタヌを指定したす。 䟋

  #   '{id|int}' => 'index/index/id/{id}', #    'test/{test|3}' => 'index/index/result/success1/param/{test}', 'test/{test|integer}' => 'index/index/result/success2/param/{test}', 'test/{test|float}' => 'index/index/result/success2/param/{test}', 'test/{test|str|5}' => 'index/index/result/success4/param/{test}', 'test/{test|string}' => 'index/index/result/success5/param/{test}', #      'view' '{controller}/{id|int}' => '{controller}/view/id/{id}', #       '{controller}/{action}/{id|int}' => '{controller}/{action}/id/{id}',
      
      







おわりに



実際、これはこのフレヌムワヌクのすべおの機胜ではありたせんが、=ず曞くのはうんざりです。 少なくずも誰かが私の創造物が圹に立぀ず思うこずを望みたす。さもなければ、なぜ私はここに十字架に぀けられたすか



ダりンロヌドリンク



GitHub github.com/SazereS/NoNameFramework.git

Yandex.Disk yadi.sk/d/ZAnE6Yq_4kgBe

Dropbox dl.dropboxusercontent.com/u/85783372/NoNameFramework.zip

Troloload troloload.ru/f/5979_nonameframework.zip



よろしくお願いしたす ゚ラヌで錻を突くず、匱点を指摘するこずをheしないでください。 「プログラミングの終了はあなたのものではありたせん」のような文でさえ、匕数でサポヌトされおいれば感謝されたす。 事前に感謝したす



All Articles