Rodhos Soft

備忘録を兼ねた技術的なメモです。Rofhos SoftではiOSアプリ開発を中心としてAndroid, Webサービス等の開発を承っております。まずはご相談下さい。

初歩的知識

以下を参照した。
saruwakakun.com

  • display:inlineは大きさ変えられない。display:blockかdisplay:inline-blockにする必要あり。aタグ, spanタグ。
  • width:autoの決まり方 基本親要素まで広がる、%指定で親要素の何%かと言う決まり方になる(このときpadding, borderをつけているとはみ出るのでbox-sizing: border-box等をつける。)。
  • min-width, max-widthで縮小に拡大に制限をつけられる。
  • height:autoは中身の分の高さになる。%指定で親の高さがきまっていないときwidthなら親の親を辿ってブラウザの幅までいきつくがheightの場合は指定がきかなくなるので注意。

htmlを吐き出す4

何か形になってきた気が。とりあえず根本的にタグを定義してみた。
しかしdivとかを手で入れるようになってしまい面倒さは変わらないような気も。

import Data.List

main = print (display html)

type ClassName = String
-- data DIV a = DIV ClassName a deriving Show
-- data P a = P ClassName a deriving Show
--
-- display:: DIV a -> String
-- display (DIV name x) = name



type TagName = String
tag::TagName -> String -> String
tag name txt = "<"++name++">" ++ txt ++ "</"++name++">"

type AttributeName = String
type AttributeString = String
attr::AttributeName -> String -> AttributeString
attr name txt = name ++ "=" ++ txt


tagatt::TagName -> [AttributeString] -> String -> String
tagatt name att txt = "<" ++ name ++ " " ++ attstr ++ ">" ++ txt ++ "</"++name++">" where
  attstr = intercalate "" att

qua::String->String
qua txt = "'" ++ txt ++ "'"

data TAG = TAG TagName ClassName [ATTRIBUTE] [TAG] |Text String deriving Show
data ATTRIBUTE = Attribute AttributeName String deriving Show

class DISPLAY a where
  display:: a -> String

instance DISPLAY TAG where
  display (TAG tagName className attributes tags) = tagatt tagName (map display ([Attribute "class" (qua className)]++attributes)) (intercalate "" (map display tags))
  display (Text txt) = txt


instance DISPLAY ATTRIBUTE where
  display (Attribute name txt) = attr name txt


-----

html = TAG "html" "" [] htmlall

htmlall = [header, body]

header = TAG "header" "" [] []
body = TAG "body" "" [] [Text "hello"]


Styleタグを付けてみた。

import Data.List

main = putStr (display html)

type ClassName = String



type TagName = String
tag::TagName -> String -> String
tag name txt = "\n<"++name++">\n" ++ txt ++ "</"++name++">\n"

type AttributeName = String
type AttributeString = String
attr::AttributeName -> String -> AttributeString
attr name txt = name ++ "=" ++ txt


tagatt::TagName -> [AttributeString] -> String -> String
tagatt name att txt = "\n<" ++ name ++ " " ++ attstr ++ ">\n" ++ txt ++ "</"++name++">\n" where
  attstr = intercalate "" att

qua::String->String
qua txt = "'" ++ txt ++ "'"

data TAG = TAG TagName ClassName [ATTRIBUTE] [TAG] |Text String deriving Show
data ATTRIBUTE = Attribute AttributeName String deriving Show

type PropertyName = String
data STYLE = STYLECLASS [ClassName] [PROPERTY] | STYLETAG TagName [PROPERTY]
data PROPERTY = Property PropertyName String deriving Show

class DISPLAY a where
  display:: a -> String

instance DISPLAY TAG where
  display (TAG tagName className attributes tags) = tagatt tagName (map display ([Attribute "class" (qua className)]++attributes)) (intercalate "" (map display tags))
  display (Text txt) = txt

instance DISPLAY ATTRIBUTE where
  display (Attribute name txt) = attr name txt

instance DISPLAY PROPERTY where
  display (Property name txt) = "\t" ++ name ++ ":" ++ txt ++ ";\n"

instance DISPLAY STYLE where
  display (STYLECLASS classnames props) = intercalate "" (map (" ."++) classnames) ++ "{\n" ++ (intercalate "" (map display props))  ++ "\n}\n"
  display (STYLETAG tagname props) = tagname ++ "{\n" ++ (intercalate "" (map display props))  ++ "\n}\n"


-----

html = TAG "html" "" [] htmlall

htmlall = [header, body]

header = TAG "header" "" [] [style]
style = TAG "style" "" [] [Text (display css)]
body = TAG "body" "hoge" [] [Text "hello"]

css = STYLECLASS ["hoge"] [Property "background-color" "green"]


タグを幾つか定義してみた。これで大体がつくれるかもしれない。

import Data.List

main = putStr (display html)

type ClassName = String



type TagName = String
tag::TagName -> String -> String
tag name txt = "\n<"++name++">\n" ++ txt ++ "</"++name++">\n"

type AttributeName = String
type AttributeString = String
attr::AttributeName -> String -> AttributeString
attr name txt = name ++ "=" ++ txt


tagatt::TagName -> [AttributeString] -> String -> String
tagatt name att txt = "\n<" ++ name ++ " " ++ attstr ++ ">\n" ++ txt ++ "</"++name++">\n" where
  attstr = intercalate "" att

qua::String->String
qua txt = "'" ++ txt ++ "'"

data TAG = TAG TagName ClassName [ATTRIBUTE] [TAG] |Text String deriving Show
data ATTRIBUTE = Attribute AttributeName String deriving Show

type PropertyName = String
data STYLE = STYLECLASS [ClassName] [PROPERTY] | STYLETAG TagName [PROPERTY] | STYLEEMPTY
data PROPERTY = Property PropertyName String deriving Show

class DISPLAY a where
  display:: a -> String

instance DISPLAY TAG where
  display (TAG tagName className attributes tags) = tagatt tagName (map display ([Attribute "class" (qua className)]++attributes)) (intercalate "" (map display tags))
  display (Text txt) = txt

instance DISPLAY ATTRIBUTE where
  display (Attribute name txt) = attr name txt

instance DISPLAY PROPERTY where
  display (Property name txt) = "\t" ++ name ++ ":" ++ txt ++ ";\n"

instance DISPLAY STYLE where
  display (STYLECLASS classnames props) = intercalate "" (map (" ."++) classnames) ++ "{\n" ++ (intercalate "" (map display props))  ++ "\n}\n"
  display (STYLETAG tagname props) = tagname ++ "{\n" ++ (intercalate "" (map display props))  ++ "\n}\n"
  display (STYLEEMPTY) = ""


-----

html = htmlcommon htmlall

htmlcommon = _html "" [Attribute "lang" (qua "ja")]
metacommon = _meta "" [Attribute "charset" (qua "UTF-8")] []
htmlall = [headtag "title" (style css) , body]

_meta = TAG "meta"
_html = TAG "html"
_head = TAG "head"
_body = TAG "body"
_div = TAG "div"
_p = TAG "p"
_a href= \className -> TAG "a" className  [Attribute "href" (qua href)]
_title = TAG "title"

style css = TAG "style" "" [] [Text (display css)]

-- head
headtag title style = _head "" [] [metacommon,style, (_title "" [] [Text title])]

-- body
body = _body "hoge" [] [_div "box" [] [Text "Hello", _a "https://yahoo.co.jp" "" [Text "link"]]]

-- css
css = STYLECLASS ["hoge"] [Property "background-color" "green"]

-- template
templatehtml title css bodytag = htmlcommon [headtag title (style css), bodytag]

-- emptyhtml
emptyhtml = templatehtml "title" STYLEEMPTY (_body "" [] [])


gistにのっけた。
html haskell · GitHub

htmlを吐き出す3

不要なデータ型を削除した少しスッキリしたが属性とかつけるとめんどくさいことになりそう。

import Data.List
main = putStr (tag_doctype ++ html)

tag_doctype = "<!DOCTYPE html>"

html = string (HTML [header,body])
header = HEAD [String "OK!"]
body =  BODY htmlbody

htmlbody = [DIV [P [String "Hello"]]]

class TransString a where
  string::a -> String
  stringjoin::[a] -> String
  stringjoin list = intercalate "" (map string list)

data Anchor = A { aURL::String, aLabel::String}
instance TransString Anchor where
  string (A { aURL=u, aLabel=l}) = (tagatt "a" (attr "href" (qua u)) l)

-- 色々なタグをタグでまとめた。
data TAG =HTML [TAG]
          |HEAD [TAG]
          |BODY [TAG]
          |TITLE [TAG]
          |DIV [TAG]
          |P [TAG]
          |String String

instance TransString TAG where
  string (HTML tags) = tag "html" (stringjoin tags)
  string (HEAD tags) = tag "head" (stringjoin tags)
  string (BODY tags) = tag "body" (stringjoin tags)
  string (TITLE tags) = tag "title" (stringjoin tags)
  string (DIV tags) = tag "div" (stringjoin tags)
  string (P tags) = tag "p" (stringjoin tags)
  string (String txt) = txt


tag::String -> String -> String
tag name txt = "<"++name++">" ++ txt ++ "</"++name++">"

attr::String -> String -> String
attr name txt = name ++ "=" ++ txt

tagatt::String -> String -> String->String
tagatt name att txt = "<" ++ name ++ " " ++ att ++ ">" ++ txt ++ "</"++name++">"

qua::String->String
qua txt = "'" ++ txt ++ "'"

trycode::(TransString a) => a -> String
trycode x = string x


divにクラスを入れるようにしてみたがこれ以上やると複雑化しそうなので別の道を考える。。

import Data.List
main = putStr (tag_doctype ++ html)

tag_doctype = "<!DOCTYPE html>"

html = string (HTML [header,body])
header = HEAD [String "OK!"]
body =  BODY htmlbody

htmlbody = [DIV "di" [P [String "Hello"]]]


class TransString a where
  string::a -> String
  stringjoin::[a] -> String
  stringjoin list = intercalate "" (map string list)

data Anchor = A { aURL::String, aLabel::String}
instance TransString Anchor where
  string (A { aURL=u, aLabel=l}) = (tagatt "a" (attr "href" (qua u)) l)

-- 色々なタグをタグでまとめた。
type ClassName = String
data TAG =HTML [TAG]
          |HEAD [TAG]
          |BODY [TAG]
          |TITLE [TAG]
          |DIV ClassName [TAG]
          |P [TAG]
          |String String

instance TransString TAG where
  string (HTML tags) = tag "html" (stringjoin tags)
  string (HEAD tags) = tag "head" (stringjoin tags)
  string (BODY tags) = tag "body" (stringjoin tags)
  string (TITLE tags) = tag "title" (stringjoin tags)
  string (DIV cname tags) = tagatt "div" (attr "class" (qua cname)) (stringjoin tags)
  string (P tags) = tag "p" (stringjoin tags)
  string (String txt) = txt


type TagName = String
tag::TagName -> String -> String
tag name txt = "<"++name++">" ++ txt ++ "</"++name++">"

type AttributeName = String
type AttributeString = String
attr::AttributeName -> String -> AttributeString
attr name txt = name ++ "=" ++ txt


tagatt::TagName -> AttributeString -> String -> String
tagatt name att txt = "<" ++ name ++ " " ++ att ++ ">" ++ txt ++ "</"++name++">"

qua::String->String
qua txt = "'" ++ txt ++ "'"

trycode::(TransString a) => a -> String
trycode x = string x

htmlを吐き出す2

html吐き出すコード、DivTag DIVとか書くのはおかしい。もっとまとまるはず。。

import Data.List
main = putStr (tag_doctype ++ html)

tag_doctype = "<!DOCTYPE html>"

html = string (HTML [header,body])
header = HeadTag (HEAD (String "OK!"))
body =  BodyTag (BODY htmlbody)

htmlbody = DivTag (DIV (PTag (P (String "Hello"))))

class TransString a where
  string::a -> String
  stringjoin::[a] -> String
  stringjoin list = intercalate "" (map string list)



data Anchor = A { aURL::String, aLabel::String}
instance TransString Anchor where
  string (A { aURL=u, aLabel=l}) = (tagatt "a" (attr "href" (qua u)) l)

-- 色々なタグをタグでまとめた。
data TAG =HTMLTag HTMLTAG
          |HeadTag HEADERTAG
          |BodyTag BODYTAG
          |TitleTag TITLETAG
          |DivTag DIVTAG
          |PTag PTAG
          |String String

instance TransString TAG where
  string (HeadTag tag) = string tag
  string (BodyTag tag) = string tag
  string (TitleTag tag) = string tag
  string (DivTag tag) = string tag
  string (PTag tag) = string tag
  string (String txt) = txt


data HTMLTAG = HTML { htmlText::[TAG]}
instance TransString HTMLTAG where
  string (HTML { htmlText=tags}) =  tag "html" (stringjoin tags)

data HEADERTAG = HEAD { headTag::TAG}
instance TransString HEADERTAG where
  string (HEAD { headTag=tag_}) = tag "head" (string tag_)

data BODYTAG = BODY { bodyTag::TAG}
instance TransString BODYTAG where
  string (BODY { bodyTag=tag_}) = tag "body" (string tag_)

data TITLETAG = TITLE { titleTag::TAG}
instance TransString TITLETAG where
  string (TITLE { titleTag=tag_}) = tag "title" (string tag_)

data DIVTAG = DIV { divTag::TAG}
instance TransString DIVTAG where
  string (DIV { divTag=tag_}) = tag "div" (string tag_)

data PTAG = P { pTag::TAG}
instance TransString PTAG where
  string (P {pTag=tag_}) = tag "p" (string tag_)

tag::String -> String -> String
tag name txt = "<"++name++">" ++ txt ++ "</"++name++">"

attr::String -> String -> String
attr name txt = name ++ "=" ++ txt

tagatt::String -> String -> String->String
tagatt name att txt = "<" ++ name ++ " " ++ att ++ ">" ++ txt ++ "</"++name++">"

qua::String->String
qua txt = "'" ++ txt ++ "'"

trycode::(TransString a) => a -> String
trycode x = string x

最初

processing.jsをダウンロードして配置する。
Processing.js


htmlを用意

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <title>title</title>
    <script src="./processing.js"></script>
  </head>
  <body>
  <canvas data-processing-sources="./proc.pde"></canvas>
  </body>
</html>

proc.pdeファイルを用意してそこにprocessingの文法で描画すればOK。例として丸を多数動かす。

int MAX = 100;
Target[] targets = new Target[MAX]; // 丸クラス

// 準備はここに描く
void setup() {
  size(1000, 1000); // サイズ指定
  frameRate(20); // 動きのフレームレート指定
  stroke(255, 0, 0); // 塗る色指定

// 丸の生成
  for (int i=0;i<MAX;i++) {
    targets[i] = new Target(random(0,1000),random(0,1000),random(-3.0,3.0),random(-3.0,3.0));
  }
}

// 描画処理はここに描く。フレームレートに応じて都度呼ばれる。
void draw() {
// 消す
  background(0);
// それぞれの丸に命令して描画させる。
  for (int i=0;i<MAX;i++) {
    Target target = (Target)targets[i];
    target.move();
    target.draw();
  }
}

// 丸
class Target {
  float x,y;
  float vx,vy;
  int id;

// 初期化
  Target(float xx, float yy, float vxx, float vyy) {
    x = xx;
    y = yy;
    vx = vxx;
    vy = vyy;
  }

// 移動
  void move() {
    x += vx;
    y += vy;
    if (x > 1000) {
      vx = abs(vx) * -1
    }
    if (x < 0) {
      vx = abs(vx)
    }

    if (y > 1000) {
      vy = abs(vy) * -1
    }
    if (y < 0) {
      vy = abs(vy)
    }
  }

// 描画
  void draw() {
    ellipse(x,y,10,10);
  }
}

ちなみにchromeからだとfile:を参照できなかったのでsafariで実行は確認した。

グラデーション

こちらのやり方にしたがってやってみた。

ics.media


しかし値の調節にこつがいるのかもしれない。

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<style>
		body {
		}
		#bg {
      position: absolute;
			top: 0;
			left: 0;
			width: 100%;
			height: 100%;
			/* 背景グラデーションの作成 */
			background: linear-gradient(to bottom,
			hsl(110, 80%, 40%), /* 色相80(360度中) 彩度 80% 輝度 40%*/
			hsl(170, 80%, 60%), /* 色相140 */
			hsl(230, 80%, 40%)); /* 色相200 */
			background-size: 400% 400%; /* 画面からはみ出させることで変化をみせてる */
      animation: AnimationName 10s ease infinite;
		}
		@keyframes AnimationName {
			0% { background-position: 50% 0% }
			50% { background-position: 50% 100%	}
			100% { background-position: 50% 0% }
		}
	</style>
</head>
<body>
<div id = "bg"></div>
</body>
</html>

flexbox

flexboxを用いて、タイル表示をしてみる。以下を参考にした。
ics.media


HTMLはヘッダーにメニューとmainにタイルとしてdivを置いた。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <title>title</title>
    <link rel="stylesheet" type="text/css" href="sample.css">
  </head>
  <body>

  <header>
    <img src="hoge.png" alt="">
    <ul>
      <li><a href="">item1</a></li>
      <li><a href="">item2</a></li>
      <li><a href="">item2</a></li>
    </ul>
  </header>


  <main>
    <!-- カード的なUI  -->
    <div class="animal">
      <h1>うなぎ</h1>
      <img src="images/unagi.jpg" alt="">
      <p>全身がなめらかな皮で覆われている魚である。</p>
    </div>

    <div class="animal">
      <h1>イルカ</h1>
      <img src="images/iruka.jpg" alt="">
      <p>魚のようだが哺乳類である。かしこい。</p>
    </div>

    <div class="animal">
      <h1>いわし</h1>
      <img src="images/iwashi.jpg" alt="">
      <p>最近高くなった。</p>
    </div>

    <div class="animal">
      <h1>どじょう</h1>
      <img src="images/dojou.jpg" alt="">
      <p>もはや見かけない</p>
    </div>
  </main>

  </body>
</html>

レイアウトでflexを用いて均等に配置等を指定する。下記で主軸といっているのが横で交差軸と言ってるのが縦の設定と思えば良い。

/*
 flexには主軸と交差軸という概念
 初期設定では主軸が左から右、交差軸が上から下
*/

/* 主軸を均等割りに */
/* 交差軸を中央に */
header {
  display: flex;
  justify-content: space-between; 
  align-items: center;
}

/* 主軸設定
  flex-start,center,flex-end,space-between(両端は端につく),space-around(両端はボックスの半分)
  交差軸設定
  stretch(親と同じ高さ),flex-start,center,flex-end
*/

/* 交差軸を中央に */
ul {
  display: flex;
  justify-content: space-between; 
  align-items: center;
}


main {
  display: flex;
  flex-wrap: wrap;  /* 複数行配置 */
}

main div.animal {
  width: calc(33.3% - 10px);
  margin: 5px;
}

HTMLヘルパーでテーブルを作る

テーブルをガリガリと書く方法とHTMLヘルパーを使って各方法を2つ並べて書いてみた。

<h1> データ </h1>
<table>
  <thead>
    <tr>
      <th>ID</th>
      <th>NAME</th>
      <th>TITLE</th>
      <th>CONTENT</th>
    </tr>
  </thead>
  <tbody>
    <?php foreach ($data as $obj): ?>
      <tr>
        <td> <?= $obj->id ?> </td>
        <td> <?= h($obj->name) ?></td>
        <td> <?= h($obj->title) ?></td>
        <td> <?= h($obj->content) ?></td>
      </tr>
    <?php endforeach; ?>
  </tbody>
</table>

<table>
  <thead>
    <tr>
      <th>ID</th>
      <th>NAME</th>
      <th>TITLE</th>
      <th>CONTENT</th>
    </tr>
  </thead>
  <?php
  $arr = $data->toArray();// 配列に取り出す
  for ($i = 0 ; $i < count($arr); $i++) {
    echo $this->Html->tableCells(
      $arr[$i]->toArray(),
      ['style' => 'background-color:#f0f0f0'],
      ['style' => 'font-weight:bold'],
      true);
  }
  ?>
</table>

PHPフレームワーク CakePHP 3入門

SQLiteの用意

CakePHPはデータベースやテーブルの設定を自分でする必要がある。大変面倒だがまずSQLiteでやってみることにする。

アプリ(例hoge)内にdbフォルダを作る(hoge/db)。

SQLiteのデータベースを作成する。

sqlite3起動

$ sqlite3 mydata
sqlite> create table 'boards' ( 'id' integer primary key autoincrement, 'name' text not null, 'title' text, 'content' text);

tableができたことを確認

sqlite> .tables
boards
sqlite> .schema boards
CREATE TABLE 'boards' ( 'id' integer primary key autoincrement, 'name' text not null, 'title' text, 'content' text);

ダミーレコードをいれておく。

sqlite> insert into 'boards' values (1,'name','test','test!');
sqlite> insert into 'boards' values (2,'name2','test2','test?');

確認

sqlite> select * from 'boards';
1|name|test|test!
2|name2|test2|test?

データベースの設定 Config/app.php

そのDatasourcesという連想配列をいじる。

<?-
// 略
    'Datasources' => [
        'default' => [
            'className' => 'Cake\Database\Connection',
            'driver' => 'Cake\Database\Driver\Mysql', // ここをSqliteに
            'persistent' => false,
            'host' => 'localhost', // 消す
            //'port' => 'non_standard_port_number',
            'username' => 'my_app', // 消す
            'password' => 'secret', // 消す
            'database' => 'my_app', // ROOT . DS . 'db' . DS . 'mydata' とする(使うファイル名を、拡張子あるならそれをつけて)。DSはパス区切りを表す。
            'encoding' => 'utf8',
            'timezone' => 'UTC',
            'flags' => [],
            'cacheMetadata' => true,
            'log' => false,

            'quoteIdentifiers' => false,

            //'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'],

            'url' => env('DATABASE_URL', null),
        ],

// 略

    ],
->


これでアプリ名にアクセス(例  ***/hoge)でwelcomeページをみて、下の方のdatabaseの項目が「CakePHP is able to connect to the database.」にチェックがついていることを確認する。

エンティティクラスの作成

src/Model/EntityにBoard.phpファイルを作成

<?php
namespace App\Model\Entity;

use Cake\ORM\Entity;

class Board extends Entity {
  // 値の一括代入用の設定 id以外のすべては一括代入可能
  protected $_accessible = [
    '*' => true,
    'id' => false
  ];
}

?>

テーブルクラスのファイルを作成

src/Model/TableにBoardsTable.phpファイルを作成

<?php 
  namespace App\Model\Table;

  use Cake\ORM\Table;

  class BoardsTable extends Table {
    
  }

 ?>

コントローラの作成

<?php
namespace App\Controller;

class BoardsController extends AppController {
  public function index() {
    $data = $this->Boards->find('all'); // $dataはQueryクラス
    $this->set('data', $data);
  }
}
?>

ビューの作成

src/Template内にBoardsフォルダを作成、index.ctpファイルを作る。

<h1> データ </h1>
<table>
  <thead>
    <tr>
      <th>ID</th>
      <th>NAME</th>
      <th>TITLE</th>
      <th>CONTENT</th>
    </tr>
  </thead>
  <tbody>
    <?php foreach ($data as $obj): ?> <!-- $objはBoardエンティティクラス -->
      <tr>
        <td> <?= $obj->id ?> </td>
        <td> <?= h($obj->name) ?></td>
        <td> <?= h($obj->title) ?></td>
        <td> <?= h($obj->content) ?></td>
      </tr>
    <?php endforeach; ?>
  </tbody>
</table>

これで表示まで一通りできた。


PHPフレームワーク CakePHP 3入門

モデル = テーブル+エンティティ

CakePHPのモデルとはテーブルとエンティティの全体を指して使う。以下のようなモデルを作ろう。

識別用のIDを持ち、投稿者名とタイトルと投稿内容を持っている情報(エンティティ)とそのエンティティの集団(テーブル)。
このモデルを「Board」と名付けよう。命名規則的には以下のような命名となる。

  1. モデル Board キャメル記法
  2. データベーステーブル boards 小文字複数形 アンダースコア記法(クラスでないので)
  3. エンティティクラス Board (Board.php) キャメル記法(クラスなので)
  4. コントローラクラス BoardsController (BoardController.php) キャメル記法(クラスなので)
  5. ビュー(テンプレート) Template/Boardsフォルダにindex.ctp等を配置

フォームヘルパーを使う

テンプレートに次のように記述。

  <p> ヘルパーを使ったフォームの送信</p>

    <p>
      <?= $result; ?>
    </p>

    <!-- FormHelperクラスを使ってformタグ生成 第1引数は値を保管するモデル名だが指定していないのでnull-->
    <?= $this->Form->create(null,
    ['type' => 'post',
    'url' => ['controller' => 'Hello', 'action' => 'index']]) ?>
    <!-- inputタグ生成 フィールド名を指定、HelloFormのところはモデル名を指定していればそれを入れる -->
    <?= $this->Form->text("HelloForm.text1") ?>

    <!-- 送信ボタンタグ -->
    <?= $this->Form->submit("送信") ?>

    <!-- タグの終了 -->
    <?= $this->Form->end(); ?>

controller側

<?php
  namespace App\Controller;

  class HelloController extends AppController {

// 略

    public function index() {

// 略

      $result = "";
      if ($this->request->isPost()) {
        $result = "<pre>送信情報<br/>";
        foreach ($this->request->data['HelloForm'] as $key => $value) {
          $result .= $key . ' => ' . $value;
        }
        $result .= "</pre>";
      } else {
        $result = "送信してください";
      }
      $this->set("result", $result);
    }

// 略


  }
?>

AppController->request連想配列

AppControllerのrequestはCakeRequestクラス。

request[種類][キー]で情報が取得できる。

種類は

  1. params 送信された値すべて
  2. data POSTされた際の内容
  3. query クエリー
  4. url 送信アドレス
  5. base ベースのディレクト
  6. webroot webrootディレクト
  7. here 現在のアドレス


PHPフレームワーク CakePHP 3入門

フォーム

フォームをテンプレートに用意

    <form method="get" action="/hello/sendForm">
      <input type="text" name="text1" />
      <inout type="submit" />
    </form>

フォームを送った先

<h1>送信結果</h1>
<p><?=$result ?></p>

ファイル名はsend_form.ctpとする。クラス、メソッド名はキャメル記法なのに対し、アンダースコア記法であることが注意するところ。

コントローラにhello/sendFormのアクションを書く

<?-
  class HelloController extends AppController {
//略
    public function sendForm() {
      $str = $this->request->query['text1']; //getで送ったものはquery連想配列に入っている。
      $result="empty.";
      if ($str != "") {
        $result = "you type:" . $str;
      }
      $this->set("result", $result);
    }
  }
->

フォームを通してでなくても

snedForm?text1=hoge

でも送れる。

ただし、XSS攻撃回避策としてタグを無効化するエスケープ処理を入れる必要がある。それには

<?=
      $this->set("result", htmlspecialchars($result));
=>

とする。

省略記法として

<?=
      $this->set("result", h($result));
=>
でも良い。

PHPフレームワーク CakePHP 3入門