cakeのviewで共通関数を読み込む

共通関数はTemplate/Element の中にctpファイルで作成します。ここではmodule.ctpとして、英語から日本語への変換処理を書きます。

<?php 

function convert($main){
	switch($main){
			case 'Clear':
				return "晴れ<img src=\"img/icon01.png\">";
				break;
			case 'Clouds':
				return "曇<img src=\"img/icon02.png\">";
				break;
			case 'Rain':
				return "雨<img src=\"img/icon03.png\">";
				break;
			default:
				echo $main;
		}
}

function convert2($description){
	switch($description){
			case 'clear sky':
				return "晴天<br>";
				break;
			case 'scattered clouds':
				return "きれぎれに浮かんでいる雲";
				break;
			case 'broken clouds':
				return "ちぎれた雲<br>";
				break;
			case 'few clouds':
				return "少しの雲<br>";
				break;
			case 'light rain':
				return "小雨<br>";
				break;
			default:
				echo $description;
		}
}

?>

Viewの共通処理の為、viewのctp(index.ctp)に1行 $this->element(‘module’) を追加します。

<?php
	$this->assign('title', '丸の内の天気');
?>
<?= $this->element('module'); ?>

<h1>丸の内の天気</h1>

<table class="table1">
	<tr>
	<?php 
	$i = 1;
	foreach ($marunouchis as $marunouchi){
	echo "<td width=\"150px\">";
	echo h($marunouchi->forecast). "<br>";
	echo convert(($marunouchi->main))."<br>";
	echo convert2(($marunouchi->description))."<br>";
	echo "気温".h($marunouchi->temp)."<br>";
	echo "湿度". h($marunouchi->humidity)."%<br>";
	echo "雲の量".h($marunouchi->cloud)."<br>";
	echo "風速".h($marunouchi->speed)."m<br>";
	echo "<td>";
	if($i % 8 == 0){
	echo "</tr><tr>";
	}
	$i++;
	}
	?>
	</tr>
</table>

おおお、なるほど

夜中の晴れは”月”のアイコンにしてみましょう。

<?php 
	$i = 1;
	foreach ($marunouchis as $marunouchi){
	echo "<td width=\"150px\">";
	echo h($marunouchi->forecast)."<br>";
	$date = h($marunouchi->forecast);
	$result = substr($date, -8);
	if($result == ' 9:00 PM' or $result == '12:00 AM' or $result == ' 3:00 AM'){
	echo convert3(($marunouchi->main))."<br>";
	} else {
	echo convert(($marunouchi->main))."<br>";
	}
	echo convert2(($marunouchi->description))."<br>";
	echo "気温".h($marunouchi->temp)."<br>";
	echo "湿度". h($marunouchi->humidity)."%<br>";
	echo "雲の量".h($marunouchi->cloud)."<br>";
	echo "風速".h($marunouchi->speed)."m<br>";
	echo "<td>";
	if($i % 8 == 0){
	echo "</tr><tr>";
	}
	$i++;
	}
	?>

cakeのdefault.cssからstyles.cssに変更する

controllerで $this->viewBuilder()->layout(‘my_layout’); と指定した後に、
webrootでcssを書いていきます。

body {
	margin:0;
	padding:10px;
	font-size: 14px;
	font-family: Verdana, sans-serif;
}

.container{
	maring: 0 auto;
}

h1 {
	margin-top:0px;
	margin-bottom: 10px;
	font-size: 20px;
	border-bottom: 1px solid #ccc;
	padding-bottom: 5px;
}

.table1 td {
	padding-bottom: 30px;
}

titleはindex.ctp

<?php
	$this->assign('title', '丸の内の天気');
?>

Elementをsrc/Template/Element/my_header.ctp追加します。

<header></header>

my_layout.ctpで、elementを追加します。

<body>
    <?= $this->element('my_header'); ?>
    <div class="container clearfix">
        <?= $this->fetch('content') ?>
    </div>
</body>

cakephpで今以降の予報を表示する

データベースの日付のフォーマットをdatetimeに変えます。

create table weather.marunouchis(
	id int unsigned auto_increment primary key,
	forecast datetime,
	main varchar(255),
	description varchar(255),
	temp float,
	humidity int,
	cloud int,
	speed float,
	created datetime default null
);

Controllerで条件を追記します。

class MarunouchisController extends AppController
{	

	public function index()
	{
		$now = date("Y-m-d H:i:s");
		$params = array(
		    'conditions' => array(
		        'forecast >' => $now, 
		    ),
		);
		$marunouchis = $this->Marunouchis->find('all', $params);
		$this->set(compact('marunouchis'));
	}
}

表示

おお、素晴らしい

index.ctpを一部改良

<h1>丸の内の天気</h1>

<table>
	<tr>
	<?php 
	$i = 1;
	foreach ($marunouchis as $marunouchi){
	echo "<td width=\"150px\">";
	echo h($marunouchi->forecast). "<br>";
	echo h($marunouchi->main)."<br>";
	echo h($marunouchi->description)."<br>";
	echo "気温".h($marunouchi->temp)."<br>";
	echo "湿度". h($marunouchi->humidity)."%<br>";
	echo "雲の量".h($marunouchi->cloud)."<br>";
	echo "風速".h($marunouchi->speed)."m<br>";
	echo "<td>";
	if($i % 8 == 0){
	echo "</tr><tr>";
	}
	$i++;
	}
	?>
	</tr>
</table>

悲しくなってきた。

controllerで呼び出す条件を制御

<?php

// /marunouchis/index

namespace App\Controller;

class MarunouchisController extends AppController
{
	public function index()
	{
		// $marunouchis = $this->Marunouchis->find('all');
		$marunouchis = $this->Marunouchis->find('all')
			->order(['id' => 'DESC']);
		$this->set(compact('marunouchis'));
	}
}
?>

idの降順で呼び出します。

idが5以上のデータを呼び出す
-> paramに条件を指定

class MarunouchisController extends AppController
{	

	public function index()
	{
		// $marunouchis = $this->Marunouchis->find('all');
		$params = array(
		    'conditions' => array(
		        'id >' => 5,
		    ),
		);
		$marunouchis = $this->Marunouchis->find('all', $params);
		$this->set(compact('marunouchis'));
	}
}

cakeでデータベースに入れたデータを表示

まずtable
MarunouchisTable.php

<?php

namespace App\Model\Table;

use Cake\ORM\Table;

class MarunouchisTable extends Table
{
	public function initialize(array $config)
	{
		$this->addBehavior('Timestamp');
	}
}
?>

続いて、Viewのindex.ctp

<h1>丸の内の天気</h1>

<ul>
	<?php foreach ($marunouchis as $marunouchi) : ?>
		<li><?= h($marunouchi->main); ?></li>
	<?php endforeach ; ?>
</ul>

最後に、Controller

<?php

// /marunouchis/index

namespace App\Controller;

class MarunouchisController extends AppController
{
	public function index()
	{
		$marunouchis = $this->Marunouchis->find('all');
		$this->set(compact('marunouchis'));
	}
}
?>

あら、いいですね。

index.ctpでtable表示してみます。

<h1>丸の内の天気</h1>

<table>
	<tr>
	<?php foreach ($marunouchis as $marunouchi) : ?>
		<td width="150px">
		<?= h($marunouchi->forecast); ?><br>
		<?= h($marunouchi->main); ?><br>
		<?= h($marunouchi->description); ?><br>
		<?= h($marunouchi->temp); ?><br>
		<?= h($marunouchi->humidity); ?><br>
		<?= h($marunouchi->speed); ?><br>
		</td>
	<?php endforeach ; ?>
	</tr>
</table>

あら♪

ルーティングも/でMarunouchisのコントローラを呼び出すように変更します。

 $routes->connect('/', ['controller' => 'Marunouchis', 'action' => 'index']);

cakeインストール時にCould not parse version constraint

cake をインストールしようと
php composer.phar create-project –prefer-dist cakephp/app weather
と打つも、エラー
Could not parse version constraint weather: Invalid version string “weather

composerをupdateとしても同じエラーメッセージ。
/usr/local/bin/composer self-update

公式ページに沿って

composer self-update && composer create-project --prefer-dist cakephp/app my_app_name

こちらなら入りました。

bin/cake server -H 192.168.33.10 -p 8000

weather mapのデータをDBに格納する

テーブル名はcakeを使うので、複数形にします。

create table weather.marunouchis(
	id int unsigned auto_increment primary key,
	forecast varchar(255),
	main varchar(255),
	description varchar(255),
	temp float,
	humidity int,
	cloud int,
	speed float,
	created datetime default null
);

PDO::PARAM_INTは、floatやdoubleはないとのこと。指定しないとstrになる。

$now = date("Y-m-d H:i:s");
$i = 0;
foreach($main as $value){
    $stmt->bindParam(':forecast', $time[$i], PDO::PARAM_STR);
    $stmt->bindParam(':main', $value, PDO::PARAM_STR);
    $stmt->bindParam(':description', $description[$i], PDO::PARAM_STR);
    $stmt->bindParam(':temp', $temp[$i], PDO::PARAM_STR);
    $stmt->bindParam(':humidity', $humidity[$i], PDO::PARAM_INT);
    $stmt->bindParam(':cloud', $cloud[$i], PDO::PARAM_INT);
    $stmt->bindParam(':speed', $speed[$i], PDO::PARAM_INT);
    $stmt->bindParam(':created', $now, PDO::PARAM_STR);
    $stmt->execute();
    $i++;
}

入っていますね。

取得した時刻が現在より未来か過去か判定する

strtotimeを使ってUNIXタイムスタンプに変換して比較します。

$now = date("Y-m-d H:i:s");
if(strtotime($now) > strtotime($list[10]["dt_txt"])){
	echo "過去の天気です。";
}else if(strtotime($now) <= strtotime($list[10]["dt_txt"])){
    echo "未来の天気です。";  
} else{
	echo "比較に失敗しました。";
}

今より、未来の天気予報を表示する

$now = date("Y-m-d H:i:s");

echo "<table class=\"table1\">";
echo "<tr>";

$i = 1;
foreach($list as $value){
	if(strtotime($now) <= strtotime($value&#91;"dt_txt"&#93;)){
	echo "<td>";
    $date = $value["dt_txt"];
    echo date('n月j日 H時', strtotime($date)). "<br>";
	echo convert($value["weather"][0]["main"]) . "<br>";
	echo "<span style=\"color:gray;\">".convert2($value["weather"][0]["description"]) . "</span><br>";
	$temp = $value["main"]["temp"];
	echo "気温 : " . number_format(($temp - 273.15),1) . "°<br>";
	echo "湿度 : " . $value["main"]["humidity"] . "%<br>";
	echo "雲 : " . $value["clouds"]["all"] . "%<br>";
	echo "風速 : " . $value["wind"]["speed"] . "m<br><br>";
	echo "</td>";
	if($i % 8 == 0){
	echo "</tr><tr>";
	}
	$i++;
	}
	

}
echo "</tr>";
echo "</table>";

なるほど、なかなかいいんじゃないでしょうか?

Yahoo天気
23区全部ありますね。。チ。

天気の英語から日本語への変換

一つづつstr_replaceで変換を考えましたが、

str_replace("Clear","晴れ", $main);

ここではswitch文を使ってみます。

foreach($list as $value){
	$main = $value["weather"][0]["main"];
		switch($main){
			case 'Clear':
				echo "晴れ<img src=\"icon01.png\"><br>";
				break;
			case 'Clouds':
				echo "曇<img src=\"icon02.png\"><br>";
				break;
			case 'Rain':
				echo "雨<img src=\"icon03.png\"><br>";
				break;
			default:
				echo $main;
		}
}

functionにします。

function convert($main){
	switch($main){
			case 'Clear':
				return "晴れ<img src=\"icon01.png\">";
				break;
			case 'Clouds':
				return "曇<img src=\"icon02.png\">";
				break;
			case 'Rain':
				return "雨<img src=\"icon03.png\">";
				break;
			default:
				echo $main;
		}
}

悪くないです。良くもないが。。

descriptionも関数を作ってみます。

function convert2($description){
	switch($description){
			case 'clear sky':
				return "晴天<br>";
				break;
			case 'scattered clouds':
				return "きれぎれに浮かんでいる雲";
				break;
			case 'broken clouds':
				return "ちぎれた雲<br>";
				break;
			case 'few clouds':
				return "少しの雲<br>";
				break;
			case 'light rain':
				return "小雨<br>";
				break;
			default:
				echo $description;
		}
}

日付形式の変換

2018-03-10 09:00:00
3月10日 09時

Y/m/d H:i:s
Y/n/j H:i:s

mはゼロ詰め、nはゼロつめなし。
dはゼロ詰め、jはゼロつめなし。

echo date('n月j日 h時', strtotime($date));

あれ、15時が03時になってますね。駄目ですね。

H大文字だと、15時、18時、21時と表示されました。

date('n月j日 H時', strtotime($date))