デバッグ lldb
ブレークポイントセット
breakpoint set -n semaphore_wait_trap
LLDB 使い方まとめ - Qiita
dispatch_barrier_sync blocks main thread when re-requesting an image. · Issue #803 · rs/SDWebImage · GitHub
script
Pythonでscript入力
exit()で終了
[LLDB] Pythonで独自コマンドを作ってみる - Qiita
https://lldb.llvm.org/python-reference.html
https://lldb.llvm.org/scripting.html
ヘルプ
help
スレッド全リスト
th list
スレッドの選択
(lldb) th sel 2
frame情報
fr info
frame選択
fr sel 1
frame内ローカル変数
fr variable
連打防止
秒数をカウントしてやる。
class DoubleTap { var actionTime:Date? = nil let actionInterval:TimeInterval = 0.3 func check() -> Bool { if let actionTime = actionTime { if -actionTime.timeIntervalSinceNow < actionInterval { return false } } self.actionTime = Date() return true } } let doubleTap:DoubleTap = DoubleTap()
事前にチェックしてfalseなら無視する。
テーブルを連携させる
2つのテーブルの連携を考える。
peapleテーブル(personの複数形)
id | INT,プライマリキー,AutoIncrement |
name | Text, Not Null, Unique |
password | Text, Not Null |
comment | Text, Null |
boardsテーブル
id | Int,プライマリキー,AutoIncrement |
person_id | Not Null |
title | Text |
content | Text |
person_idは外部キーということになる。
テーブルの結合
3つのJOIN
- LEFT JOIN
- RIGHT JOIN
- INNER JOIN
わかりやすい解説があった。
A Visual Explanation of SQL Joins
このリンクを読んだ後以下を読むと意味がわかる。
qiita.com
bake
bookモデルを作りそのCRUDをbakeで作る。
データベースでbooksテーブル作成
id | 整数、プライマリー、自動インクリメント |
title | テキスト |
author | テキスト |
price | 整数 |
bake
$ ./bin/cake bake all books
しかし失敗する
Exception: SQLSTATE[HY000] [2002] Connection refused in [*****/hogemysql/vendor/cakephp/cakephp/src/Database/Driver/PDODriverTrait.php, line 47]
Config/app.php で 以下のようにhostとportを設定したところ通った。
'Datasources' => [ 'default' => [ // 略 'host' => '127.0.0.1', 'port' => '8889', // 略 ],
これだけで追加、編集等の画面毎作れる。
TableのvalidationDefault
bakeしたtableにはバリデーションが設定されている。
public function validationDefault(Validator $validator) { $validator ->integer('id') ->allowEmpty('id', 'create'); $validator ->requirePresence('title', 'create') ->notEmpty('title'); $validator ->requirePresence('author', 'create') ->notEmpty('author'); $validator ->integer('price') ->requirePresence('price', 'create') ->notEmpty('price'); return $validator; }
データベース操作
レコード追加
テンプレー側にフォームを用意
<?= $this->Form->Create($entity, ['url'=>['action'=>'addRecord']]) ?> <fieldset> <?= $this->Form->text("name") ?> <?= $this->Form->text("title") ?> <?= $this->Form->textarea("content") ?> </fieldset> <?= $this->Form->button("送信") ?> <?= $this->Form->end() ?>
コントローラにaddRecord追加
<?php namespace App\Controller; class BoardsController extends AppController { public function index() { $data = $this->Boards->find('all'); $this->set('data', $data); $this->set('entity', $this->Boards->newEntity());/* 空のものをセット*/ } public function addRecord() { if ($this->request->is('post')) { $board = $this->Boards->newEntity($this->request->data); $this->Boards->save($board); } return $this->redirect(['action' => 'index']); } } ?>
request_dataの中身確認
中身をprintしてみる
public function addRecord() { if ($this->request->is('post')) { $board = $this->Boards->newEntity($this->request->data); $this->Boards->save($board); } $this->autoRender = false; echo "<pre>"; print_r($this->request->data); echo "</pre>"; // return $this->redirect(['action' => 'index']); }
結果、
このような連想配列が入っていることがわかった。
Array ( [name] => hoge [title] => hello [content] => I have a pen. )
レコードの検索
特定レコード表示をfindを使って実装する。index.ctpに以下を追加
<h2>検索</h2> <?= $this->Form->Create($entity, ['url'=>['action'=>'index']]) ?> <fieldset> <?= $this->Form->text("id") ?> </fieldset> <?= $this->Form->button("送信") ?> <?= $this->Form->end() ?>
コントローラのindexを修正
public function index() { $this->set('entity', $this->Boards->newEntity()); if ($this->request->is('post')) { $data = $this->Boards->find('all', ['conditions' => ['id' => $this->request->data['id']]] ); } else { $data = $this->Boards->find('all'); } $this->set('data', $data); }
find
第1引数
all | 全レコード |
list | レコードのリスト(表示用のフィールドだけ入っている) |
threaded | スレッド状レコード(ネストされたエンティティを扱う際に必要) |
第2引数
conditions | 条件設定 |
fields | 取得するフィールド名を配列として用意 |
recursive | 再帰的に取得する深度 |
order | 取得順 |
limit | 上限 |
offset | 取得開始位置 |
page | 取得ページ数 |
like 検索
テンプレートをidからtitleに書き換え
<h2>検索</h2> <?= $this->Form->Create($entity, ['url'=>['action'=>'index']]) ?> <fieldset> <?= $this->Form->text("name") ?> </fieldset> <?= $this->Form->button("送信") ?> <?= $this->Form->end() ?>
コントローラもlikeを使ったものにかきかえ
public function index() { $this->set('entity', $this->Boards->newEntity()); if ($this->request->is('post')) { $data = $this->Boards->find('all', ['conditions' => ['name like' => "%{$this->request->data['name']}%"] ] ); } else { $data = $this->Boards->find('all'); } $this->set('data', $data); }
これでその文字を含むnameの検索になった。
findで取得したQueryを調べる。
コントローラにindexを生やして出力させてみた。
public function findtest() { $query = $this->Boards->find('all'); $this->autoRender = false; echo "<div>"; echo "数"; echo "<pre>"; print_r($query->count()); echo "</pre>"; echo "</div>"; echo "<div>"; echo "first"; echo "<pre>"; print_r($query->first()->toArray()); echo "</pre>"; echo "</div>"; echo "<div>"; echo "last"; echo "<pre>"; print_r($query->last()->toArray()); echo "</pre>"; echo "</div>"; echo "<div>"; echo "max_id"; echo "<pre>"; print_r($query->max('id')); echo "</pre>"; echo "</div>"; echo "<div>"; echo "min_id"; echo "<pre>"; print_r($query->min('id')); echo "</pre>"; echo "</div>"; }
結果は
数 4 first Array ( [id] => 1 [name] => poi [title] => asdasd [content] => fawefsfawefaewf ) last Array ( [id] => 1 [name] => poi [title] => asdasd [content] => fawefsfawefaewf ) max_id Cake\ORM\Entity Object ( [id] => 1 [name] => poi [title] => asdasd [content] => fawefsfawefaewf [[new]] => [[accessible]] => Array ( [*] => 1 ) [[dirty]] => Array ( ) [[original]] => Array ( ) [[virtual]] => Array ( ) [[errors]] => Array ( ) [[invalid]] => Array ( ) [[repository]] => Boards ) min_id Cake\ORM\Entity Object ( [id] => 1 [name] => poi [title] => asdasd [content] => fawefsfawefaewf [[new]] => [[accessible]] => Array ( [*] => 1 ) [[dirty]] => Array ( ) [[original]] => Array ( ) [[virtual]] => Array ( ) [[errors]] => Array ( ) [[invalid]] => Array ( ) [[repository]] => Boards )
firstとlastがおなじになっている。
これは$data->$first とやったことでqueryの内容が変わってしまったことを意味する。
そうならないようにすると(取り直した)
public function findtest() { $query = $this->Boards->find('all'); $count = $query->count(); $max_id = $query->max('id'); $min_id = $query->min('id'); $first = $this->Boards->find('all')->first(); $last = $this->Boards->find('all')->last(); $this->autoRender = false; echo "<div>"; echo "数"; echo "<pre>"; print_r($count); echo "</pre>"; echo "</div>"; echo "<div>"; echo "first"; echo "<pre>"; print_r($first->toArray()); echo "</pre>"; echo "</div>"; echo "<div>"; echo "last"; echo "<pre>"; print_r($last->toArray()); echo "</pre>"; echo "</div>"; echo "<div>"; echo "max_id"; echo "<pre>"; print_r($max_id); echo "</pre>"; echo "</div>"; echo "<div>"; echo "min_id"; echo "<pre>"; print_r($min_id); echo "</pre>"; echo "</div>"; }
確かに正常に検索結果がでている。
数 4 first Array ( [id] => 1 [name] => poi [title] => asdasd [content] => fawefsfawefaewf ) last Array ( [id] => 4 [name] => hoge [title] => hello [content] => I have a pen. ) max_id Cake\ORM\Entity Object ( [id] => 4 [name] => hoge [title] => hello [content] => I have a pen. [[new]] => [[accessible]] => Array ( [*] => 1 ) [[dirty]] => Array ( ) [[original]] => Array ( ) [[virtual]] => Array ( ) [[errors]] => Array ( ) [[invalid]] => Array ( ) [[repository]] => Boards ) min_id Cake\ORM\Entity Object ( [id] => 1 [name] => poi [title] => asdasd [content] => fawefsfawefaewf [[new]] => [[accessible]] => Array ( [*] => 1 ) [[dirty]] => Array ( ) [[original]] => Array ( ) [[virtual]] => Array ( ) [[errors]] => Array ( ) [[invalid]] => Array ( ) [[repository]] => Boards )
昇順、降順
orderを使う。
public function findtest() { $query = $this->Boards->find('all'); $query->order(['name' => 'ASC', 'id' => 'DESC']); $this->autoRender = false; echo "<div>"; echo "<pre>"; print_r($query->toArray()); echo "</pre>"; echo "</div>"; }
動的FInderで検索 findBy___()
以下のようにキャメル記法でフィールド名をByの後に書く。
public function findtest() { $query = $this->Boards->findById('1'); $this->autoRender = false; echo "<div>"; echo "<pre>"; print_r($query->toArray()); echo "</pre>"; echo "</div>"; }
2つの条件をorで結びたい場合
$query = $this->Boards->findByIdOrName('1',"poi");
andも同様。
削除
<h2>削除</h2> <?= $this->Form->Create($entity, ['url'=>['action'=>'deleteRecord']]) ?> <fieldset> <?= $this->Form->text("id") ?> </fieldset> <?= $this->Form->button("送信") ?> <?= $this->Form->end() ?>
コントローラに
use \Exception;
use Cake\Log\Log;
を追加しつつ、以下を追加
public function deleteRecord() { if ($this->request->is('post')) { try { $entity = $this->Boards->get($this->request->data['id']); $this->Boards->delete($entity); } catch (Exception $e) { Log::write('debug', $e->getMessage()); } } $this->redirect(['action' => 'index']); }
IDがプライマリーキーなのでエンティティがgetで得られる。
Logはレベルを指定して出力できる。
debug | デバッグ |
info | 情報 |
notice | 注意 |
warning | 警告 |
error | 例外 |
critical | 危険 |
alert | 直ちに対処すべき |
emergency | システム停止級 |
条件の範囲を消したい時、例えばnameがhogeのものすべてを消す場合、
$this->Boards->deleteAll(['name' => 'hoge']);
レコードの更新
saveで良い。
index側
<h2>編集</h2> <?=$this->Form->create($entity, ['url'=>['action'=>'editRecord']]) ?> <fieldset> <p><?= 'ID =' . $entity->id ?></p> <?=$this->Form->hidden("id") ?> <?=$this->Form->text("name") ?> <?=$this->Form->text("title") ?> <?=$this->Form->text("content") ?> </fieldset> <?=$this->Form->button("送信") ?> <?=$this->Form->end() ?>
コントローラ側
public function index($id = null) { $this->set('entity', $this->Boards->newEntity()); if ($id != null) { try { $entity = $this->Boards->get($id); $this->set('entity', $entity); } catch (Exception $e){ Log::write('debug', $e->getMessage()); } } $data = $this->Boards->find('all')->order(['id'=>'DESC']); $this->set('data', $data->toArray()); } public function editRecord() { // putに注意 if ($this->request->is('put')) { try { $entity = $this->Boards->get($this->request->data['id']); $this->Boards->patchEntity($entity, $this->request->data); $this->Boards->save($entity); } catch (Exception $e) { Log::write('debug', $e->getMessage()); } } $this->redirect(['action' => 'index']); }
これでboards/index/1のようにアクセスして編集できる。
■
使いかた
http://pubman.mpdl.mpg.de/pubman/item/escidoc:150722:1/component/escidoc:150721/cadabra.pdf
A brief introduction to Cadabra: a tool for tensor computations in General Relativity
https://arxiv.org/pdf/0903.2085.pdf
https://suppiya.files.wordpress.com/2008/05/comprund_41_016.pdf
sympy
ツリー構造
Advanced Expression Manipulation — SymPy 1.0.1.dev documentation
Taming math and physics using SymPy
https://minireference.com/static/tutorials/sympy_tutorial.pdf
使えるかというと微妙
500エラー
PHPでエラーがみたい
php.iniファイルで
error_reporting = E_ALL display_errors On display_startup_errors = On
公開用サーバではlog_errorsでログでみるべき。
internal error 500
新しくプロジェクトを作ったところそのようなエラーがでた。
ログを確認したところ
PHP Fatal error: require(): Failed opening required '/Applications/MAMP/htdocs/hogemysql/vendor/autoload.php' (include_path='.:/Applications/MAMP/bin/php/php7.1.1/lib/php') in /Applications/MAMP/htdocs/hogemysql/webroot/index.php on line 27 PHP Warning: require(/Applications/MAMP/htdocs/hogemysql/vendor/autoload.php): failed to open stream: No such file or directory in /Applications/MAMP/htdocs/hogemysql/webroot/index.php on line 27
つまりautoload.phpがないといわれている。
同様の問題と思わしきページ
chaika.hatenablog.com
たしかにログをみてみると
$ php composer.phar create-project --prefer-dist cakephp/app hogemysql Installing cakephp/app (3.4.2) - Installing cakephp/app (3.4.2): Downloading (100%) Created project in hogemysql Loading composer repositories with package information Updating dependencies (including require-dev) Your requirements could not be resolved to an installable set of packages. Problem 1 - cakephp/cakephp 3.4.7 requires ext-intl * -> the requested PHP extension intl is missing from your system. - cakephp/cakephp 3.4.6 requires ext-intl * -> the requested PHP extension intl is missing from your system. - cakephp/cakephp 3.4.5 requires ext-intl * -> the requested PHP extension intl is missing from your system. - cakephp/cakephp 3.4.4 requires ext-intl * -> the requested PHP extension intl is missing from your system. - cakephp/cakephp 3.4.3 requires ext-intl * -> the requested PHP extension intl is missing from your system. - cakephp/cakephp 3.4.2 requires lib-icu >=4.8 -> the requested linked library icu has the wrong version installed or is missing from your system, make sure to have the extension providing it. - cakephp/cakephp 3.4.1 requires lib-icu >=4.8 -> the requested linked library icu has the wrong version installed or is missing from your system, make sure to have the extension providing it. - cakephp/cakephp 3.4.0 requires lib-icu >=4.8 -> the requested linked library icu has the wrong version installed or is missing from your system, make sure to have the extension providing it. - Installation request for cakephp/cakephp 3.4.* -> satisfiable by cakephp/cakephp[3.4.0, 3.4.1, 3.4.2, 3.4.3, 3.4.4, 3.4.5, 3.4.6, 3.4.7].
とintlがないと言われている。
qiita.com
の手順でやってみた。
icu4cインストール(Unicode 関連の処理を行うためのオープンソースのライブラリ)
$ brew install icu4c
autoconfインストール(https://ja.wikipedia.org/wiki/Autotools#autoconf)
が、うまくいかない。
Error: No available formula with the name "icu4cautoconf" ==> Searching for similarly named formulae... Error: No similarly named formulae found. ==> Searching taps... Error: No formulae found in taps. ==> You haven't updated Homebrew in a while.
brew updateしようとしたが
Error: /usr/local must be writable!
とありあえず
brew doctor
してみた。
それにしたがい
sudo chown -R $(whoami) /usr/local
をする。
brew update
が実行できたが
Error: update-report should not be called directly!
もう一度
brew install autoconf
$ sudo pecl update-channels $ sudo pecl install intl
sudo: pecl: command not found
遠回りしている気がしたので
brew search intl intltool homebrew/php/php53-intl homebrew/php/php55-intl homebrew/php/php71-intl homebrew/php/php54-intl homebrew/php/php56-intl homebrew/php/php70-intl
brew install homebrew/php/php71-intl
webアプリのフォルダで
composer install
これでアクセスしたところ表示が500から
Could not load configuration file: /Applications/MAMP/htdocs/hogemysql/config/app.php
に変わった。
もう一度
composer install
したところ
$ composer install Loading composer repositories with package information Installing dependencies (including require-dev) from lock file Nothing to install or update Generating autoload files > Cake\Composer\Installer\PluginInstaller::postAutoloadDump > App\Console\Installer::postInstall Created `config/app.php` file Set Folder Permissions ? (Default to Y) [Y,n]? Y Permissions set on /Applications/MAMP/htdocs/hogemysql/tmp/cache Permissions set on /Applications/MAMP/htdocs/hogemysql/tmp/cache/models Permissions set on /Applications/MAMP/htdocs/hogemysql/tmp/cache/persistent Permissions set on /Applications/MAMP/htdocs/hogemysql/tmp/cache/views Permissions set on /Applications/MAMP/htdocs/hogemysql/tmp/sessions Permissions set on /Applications/MAMP/htdocs/hogemysql/tmp/tests Permissions set on /Applications/MAMP/htdocs/hogemysql/tmp Permissions set on /Applications/MAMP/htdocs/hogemysql/logs Updated Security.salt value in config/app.php
となり、無事アクセスが成功した。
whoamiとは
MySQL
phpMyAdminがつかえるとして以下話をする。
MySQLにパスワードを設定している場合は
phpMyAdmin/config.inc.php
の
$cfg['Servers'][$i]['user'] = '*****'; $cfg['Servers'][$i]['password'] = '****';
を設定する。
phpMyAdminでデータベース作成
mydata 照合順序 utf8_nicode_ci
テーブル作成
boards フィールド数4
フィールド設定
id | INT | PRIMARY | A_I |
name | VARCHAR(255) | Null | |
title | VARCHAR | ||
content | TEXT |
CREATE TABLE `mydata`.`boards` ( `id` INT NOT NULL AUTO_INCREMENT , `name` VARCHAR(255) NULL , `title` VARCHAR(255) NOT NULL , `content` TEXT NOT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB;
ダミーレコード入力
挿入で適当に数件入れる。
INSERT INTO `boards` (`id`, `name`, `title`, `content`) VALUES (NULL, 'poi', 'asdasd', 'fawefsfawefaewf'); INSERT INTO `boards` (`id`, `name`, `title`, `content`) VALUES (NULL, 'piopoi', 'asdasd', 'ddddddddddwwwwwssssxxxx');
CakePHPのデータベースファイルをMySQLに変更する
Config/app.php
'Datasources' => [ 'default' => [ 'className' => 'Cake\Database\Connection', 'driver' => 'Cake\Database\Driver\Mysql', 'persistent' => false, 'host' => 'localhost', /** * CakePHP will use the default DB port based on the driver selected * MySQL on MAMP uses port 8889, MAMP users will want to uncomment * the following line and set the port accordingly */ //'port' => 'non_standard_port_number', 'username' => '****', 'password' => '****', 'database' => 'mydata', 'encoding' => 'utf8', 'timezone' => 'UTC', 'flags' => [], 'cacheMetadata' => true, 'log' => false, 'quoteIdentifiers' => false, 'url' => env('DATABASE_URL', null), ],
表示用意
例によってコントローラ用意
<?php namespace App\Controller; class BoardsController extends AppController { public function index() { $data = $this->Boards->find('all'); $this->set('data', $data); } } ?>
エンティティとテーブル用意
<?php namespace App\Mode\Entity; use Cake\ORM\Entity; class Board extends Entity { protected $_accessible = [ '*' => true, 'id' => false ]; } ?>
<?php namespace App\Model\Table; use Cake\ORM\Table; class BoardsTable extends Table { } ?>
ビューの作成
Template/Boards/index.ctp
<h1>DataBase</h1> <table> <tr> <th>ID</th> <th>Title</th> <th>Content</th> </tr> <?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>
おさらい
いままでのおさらい。
プロジェクト作成
mkdir hoge
php composer.phar create-project --prefer-dist cakephp/app hoge
Hello World
<?php namespace App\Controller; class HelloController extends AppController { public $autoRender = false; public function index() { echo "hello world!!"; } } ?>
hello/other
<?php namespace App\Controller; class HelloController extends AppController { public $autoRender = false; public function index() { echo "hello, world!!"; } public function other() { echo "hello, other world!!"; } } ?>
フォワードとリダイレクション
<?php namespace App\Controller; class HelloController extends AppController { public $name = "Hello"; public $autoRender = false; public function index() { echo "hello, world!!"; } public function other() { echo "hello, other world!!"; } // アクションを指定 public function forw() { $this->setAction(other); } // ブラウザにベージ移動を依頼する public function red() { $this->redirect("/hello/other"); } } ?>
テンプレート
作る場所の例
src/Template/Hello/index.ctp
<!DOCTYPE html> <html lang="ja"> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <title>Hello Page</title> </head> <body> <h1>midashi</h1> <p> hello hello </p> </body> </html>
コントローラ側でautoRenderをtrueにしてテンプレートを読み込む。
<?php namespace App\Controller; class HelloController extends AppController { public $name = "Hello"; public $autoRender = true; public function index() { $this->viewBuilder()->autoLayout(false); } } ?>
autoLayoutをtrueにする場合、テンプレートは
<h1>midashi</h1> <p> hello hello </p>
だけでよく、デフォルトのsrc/Template/Layout/default.ctp
が適用される。
レイアウト
スタイルシートを用意する。
webroot/css/cake.hello.css
body { background: #eee; color: #999; margin: 10px 8px } #header { font-size: 18pt; font-weight: bold; margin: 10px; } #content { background: #fff; color: #999; padding: 10px 25px 30px 25px; font-size: 14pt; } #footer { text-align: right; font-size: 12pt; margin: 10pt; } h1 { color: #aaa; font-size: 24pt; margin: 20pt 0pt 50pt 0pt; }
cssを利用する側のテンプレートを書く
src/Template/Layout/hello.ctp
<!DOCTYPE html> <html> <head> <?= $this->Html->charset() ?> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title> <?= $this->fetch('title') ?> </title> <?= $this->Html->meta('icon') ?> <?= $this->Html->css('cake.hello.css') ?> <?= $this->fetch('meta') ?> <?= $this->fetch('css') ?> <?= $this->fetch('script') ?> </head> <!-- fetchでコントローラの変数を取ってきている。 --> <body> <div id="container"> <div id="header">header</div> <div id="content"> <?=$this->fetch('content') ?> </div> <div id="footer">footer</div> </body> </html>
jsも使いたい場合、ファイルをwebroot/js/cake.hello/jsに用意し、
<?= $this->Html->script('cake.hello.js') ?>
を追加する。
最後に、コントローラでレイアウトを指定する。
<?php namespace App\Controller; class HelloController extends AppController { public $name = "Hello"; public $autoRender = true; public function index() { $this->ViewBuilder()->layout('Hello'); } } ?>
エレメント
レイアウトにはめ込んで使える。Templete/Elementフォルダにいれておき、
<?= $this->element('hoge') ?>
で読み込める。
値を渡す場合
<?= $this->element('hoge', ['x'=>10,'y'=>5]) ?>
値の受け渡し
コントローラからテンプレートへ
$this->set('poi',10);
テンプレート側は
<p> <?= $poi ?> </p>
AppController->requestの連想配列
params | 送信された値すべて |
data | POSTされた際の内容 |
query | クエリー |
url | 送信アドレス |
base | ベースのディレクトリ |
webroot | webrootディレクトリ |
here | 現在のアドレス |
フォームヘルパー
テンプレート側
<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(); ?>
コントローラ側
<?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); } // 略 } ?>
モデル = テーブル + エンティティ
例としてBoardモデルを考える
モデル | Board | キャメル記法 |
データベーステーブル | boards | 小文字複数形 アンダースコア記法(クラスでないので) |
エンティティ | Board | Board.php キャメル記法(クラスなので) |
コントローラ | BoardsController | BoardController.php キャメル記法(クラスなので) |
ビュー(テンプレート) | Template/Boards | index.ctp等を配置 |
SQLiteの用意
SQLite3で自前で作る。ダミーレコードもいれておく
$ sqlite3 mydata sqlite> 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?');
.tables, select * from 'boards'等で確認
データベース設定
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>
HTMLヘルパーでテーブルを作る
<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>
技術英語
WWDCをみつつ
Existentials 存在に関する(実存的な)
Compilation コンパイル、編集物
Inference 推論
thunks サンク 遅延評価を受ける関数に受け渡す引数
ストリーム (プログラミング) - Wikipedia
inception 開始、発端
Interruptible 中断可能、割り込み可能
subvert 倒す、破壊する、覆す
elapse 経過する、過ぎ去る
WWDC2017
iOS11の忘備録
まずQiitaを一読して後追いする。WWDC2017を個別にみていきたい。恐らくリンク先の堤さん等のまとめ(API Diffsから見る iOS 11 の新機能 #WWDC17 - Over&Out その後)
を読むほうが早い..。
以下作成中
レビュー催促ポップアップの規制
Apple、アプリ上でレビューを催促するポップアップを今後は規制
iphone-mania.jp
iOS10.3からSKStoreReviewController
これに一本化される。
MusicKit
iTuneの曲の再生、プレイリスト取得等
MusicKit - Apple Developer
qiita.com
MapKit機能追加
MKMarkerAnnotationViewが追加されたのが大きいような気がする。表示の優先順位とかもつけられるようになった。
qiita.com
Core ML
機械学習系、学習済みのものを使ったりできる。appleが幾つか学習済みデータのサンプルを以下で提供しているのでそれを使ってみるのが良いかも。
少し調べる必要がある。
d.hatena.ne.jp
Machine Learning - Apple Developer
Core ML | Apple Developer Documentation
Depth API
デュアルレンズを使った奥行き判定。AVCaptureDepthDataOutput。
d.hatena.ne.jp
AVCaptureDepthDataOutput - AVFoundation | Apple Developer Documentation
SiriKit機能追加
各種インテントが増えてる。公演のPDF参照。
INTransferMoneyIntent, INSearchForAccountsIntent, INCreateTaskListIntent, INAddTasksIntent, INSetTaskAttributeIntent, INSearchForNotebookItemsIntent,
INGetVisualCodeIntent,
developer.apple.com
SiriKit - Apple Developer
https://devstreaming-cdn.apple.com/videos/wwdc/2017/214bugobsy7xw94v/214/214_whats_new_in_sirikit.pdf
ReplayKit機能追加
RPScreenRecorderというデバイス画面の動画を取れるクラス(AVPlayerからはとれない。)にstartCaptureが追加された。
d.hatena.ne.jp
RPScreenRecorder - ReplayKit | Apple Developer Documentation
SceneKit機能追加
scncameracontroller 情報がない。
SCNCameraController - SceneKit | Apple Developer Documentation
ちなみにSCNCameraとは
SCNCamera - SceneKit | Apple Developer Documentation
NEHotspotConfiguration, NEHotspotConfigurationManager
特定のwifiにワンタップで自動でつなげるような感じなのだろうか。。 NEHotspotHelperはiOS9からある。
[iOS] Wi-Fi一覧でアピール表示し、パスワードを自動入力して接続させる方法(とまとレストランの販売促進アプリ) | Developers.IO
NEHotspotConfiguration - NetworkExtension | Apple Developer Documentation
NEHotspotConfigurationManager - NetworkExtension | Apple Developer Documentation
Advances in Networking, Part 1 - WWDC 2017 - Videos - Apple Developer
developer.apple.com
ARKit
ARSCNViewやARSKViewは ARSessionを含む。Sessionを動かすにはconfigがいる。ARSessionConfiguration, ARWorldTrackingSessionConfiguration。
ARSession - ARKit | Apple Developer Documentation
WWDC2017ARKIT
developer.apple.com
ARKitはAVFoudationとCoreMotionを使う。ARSessionConfigを設定してARSessionをRunする。ARSessionはAVCaptureSessionとCMMotionManagerを使う。
現在のフレームがARFrame。
特定の位置等をARAnchorで付けたりできる。ARCameraにTracking stateなどの状態が入る(ARSessionから状態通知)。
シーン(場面)の理解としてどこが平面化の理解というのができる。configuration.planeDetection とかで指定しておく。hitTestが frame.hitTestでできる。
Renderingについては
SceneKit のARSCNView
SpriteKitのARSKView
メタルでCustom Renderingする
等がある。
SceneKitはiOS8から使える簡易3D描画フレームワーク。
qiita.com
サンプルコード
github.com
github.com
アニメーション
iOS10から導入されたUIViewPropertyAnimatorに
iOS11で
scrubsLinearly:、pausesOnCompletion:が加わる。
CALayerに.maskedCorners:CACornerMaskが加わる。
Foundation
キーパスが簡単に
let age = ben[keyPath: \Kid.age] ben[keyPath: \Kid.nickname] = "Ben"
KVOも
let observation = mia.observe(\.age) { }
Codableについて
略
AVPlayer
初歩的知識
以下を参照した。
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