TOPページ(ホームページ)を設ける前に、MVC(Model-View-Controller)に関する基本設定が必要です。
% cd ~/www/config
% cp app.php ~/files
% vi app.php
% diff ~/files/app.php app.php
55,56c55,56
< 'defaultLocale' => env('APP_DEFAULT_LOCALE', 'en_US'),
< 'defaultTimezone' => env('APP_DEFAULT_TIMEZONE', 'UTC'),
---
> 'defaultLocale' => env('APP_DEFAULT_LOCALE', 'ja_JP'),
> 'defaultTimezone' => env('APP_DEFAULT_TIMEZONE', 'Asia/Tokyo'),
292c292
< 'timezone' => 'UTC',
---
> 'timezone' => 'timezone',
335c335
< 'timezone' => 'UTC',
---
> 'timezone' => 'timezone',
%
当資料ではDebugKitを無効にしているため、デバッグ用の広域関数を用意します。 ~/www/logs/appl.logファイルに記録されます。
% cd ~/www/config
% vi my_define.php
% cat my_define.php
<?php
define('APPLOG', LOGS . 'app.log'); // デバッグ用アプリケーションログ
% vi my_func.php
% cat my_func.php
<?php
function applog($val)
{
$bktr = debug_backtrace();
$file = $bktr[0]['file'];
$line = $bktr[0]['line'];
error_log(date('Y-m-d H:i:s') . ' ' . $file . ':' . $line . "\n" . var_export($val, true) . "\n", 3, APPLOG);
}
% cp bootstrap.php ~/files
% vi bootstrap.php
% diff ~/files/bootstrap.php bootstrap.php
250a251,256
>
> /*
> * Global Function
> */
> include 'my_define.php';
> include 'my_func.php';
%
DDL(Data Definition Language)ファイル(ddl.sql)を作成し、MySQLで実行します。
% cd ~/db
% vi ddl.sql
% cat ddl.sql
--
-- accountname01_schemename は [コントロールパネル]で作成したデータベース(スキーマ)です。
-- MySQLの場合、データベースとスキーマは同じ意味を持ちます。
--
use `accountname01_schemename`
--
-- クリーンアップ
--
DROP TABLE IF EXISTS `c_copyright`;
--
-- 版権情報
--
CREATE TABLE IF NOT EXISTS `c_copyright` (
`begin_year` INT NOT NULL COMMENT '開始年',
`message` TEXT NOT NULL COMMENT '版権'
) ENGINE=InnoDB COMMENT '版権情報';
--
-- 初期値
--
INSERT INTO `c_copyright` (`begin_year`, `message`) VALUES
(2026, 'half-of-string.com. All Rights Reserved.');
-- End Of Line
%
・~/www/webroot/jsにファイルを追加する。
bootstrap.bundle.min.js
bootstrap.esm.min.js
bootstrap.min.js
jquery-3.7.1.min.js
・~/www/webroot/cssにファイルを追加する。
bootstrap-grid.min.css
bootstrap-grid.rtl.min.css
bootstrap-reboot.min.css
bootstrap-reboot.rtl.min.css
bootstrap-utilities.min.css
bootstrap-utilities.rtl.min.css
bootstrap.min.css
bootstrap.rtl.min.css
・当サイト用cssを用意。
% cd ~/www/webroot/css
% vi my.css
CakePHPの制約を緩める変更を行います。
Model:
~/www/src/Model/AppModel.php // SQLを直接使用できるようにします。
~/www/src/Model/BasicModel.php // 当サイトの基本情報をDBから取得します。
View:
~/www/templates/layout/my_default.php
Controller:
~/www/src/Controller/AppController.php
% cd ~/www/src/Model
% vi AppModel.php
% cat AppModel.php
<?php
declare(strict_types=1);
namespace App\Model;
use Cake\Datasource\ConnectionManager;
/**
* Application Model
*/
class AppModel
{
private $_config;
private $_mysqli;
function __construct() {
$this->_config = ConnectionManager::get('default')->config();
}
public function connect() {
$this->_mysqli = new \mysqli($this->_config['host'], $this->_config['username'], $this->_config['password'], $this->_config['database']);
if ($this->_mysqli->connect_error) {
return $this->_mysqli->connect_error;
} else {
$this->_mysqli->set_charset('utf8');
$this->_mysqli->autocommit(FALSE);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
}
return '';
}
public function close() {
$this->_mysqli->close();
}
public function begin() {
$this->_mysqli->begin_transaction();
}
public function commit() {
$this->_mysqli->commit();
}
public function rollback() {
$this->_mysqli->rollback();
}
public function esc($val) {
$str = (gettype($val) == 'string') ? $val : (string)$val;
return $this->_mysqli->real_escape_string($str);
}
public function query($sql) {
return $this->_mysqli->query($sql);
}
public function insert_id() {
return $this->_mysqli->insert_id;
}
public function getRecord($sql) {
$ans = [];
if ($result = $this->_mysqli->query($sql)) {
while ($row = $result->fetch_assoc()) {
$ans[] = $row;
}
$result->close();
}
return $ans;
}
}
%
% cd ~/www/src/Model
% vi BasicModel.php
% cat BasicModel.php
<?php
declare(strict_types=1);
namespace App\Model;
/**
* Basic Model
*/
class BasicModel extends AppModel
{
public function getBasicInfo() {
$this->connect();
$sql = "SELECT `begin_year`, `message`"
. " FROM `c_copyright`"
;
$rec = $this->getRecord($sql);
$this->close();
return (empty($rec[0])) ? [] : $rec[0];
}
}
%
% cd ~/www/templates/layout
% vi my_default.php
% cat my_default.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<title>halh-of-string</title>
<link href="/css/bootstrap.min.css" rel="stylesheet">
<link href="/css/my.css?<?=date('Ymdhis')?>" rel="stylesheet">
<link href="/favicon.ico?<?=date('Ymdhis')?>" rel="shortcut icon">
</head>
<body>
<div class="container text-center" id="my_main">
<header class="navbar navbar-expand-lg navbar-light bg-light p-1">
<div class="container-fluid" id="my_nav">
<div class="col"><p class="fw-bolder"><?= $header_message ?></p></div>
</div>
</header>
<div style="height: 18px;"> </div>
<div id="my_content">
<?= $this->fetch('content') ?>
</div>
<div style="height: 18px;"> </div>
<footer class="d-flex flex-wrap align-items-center justify-content-center" id="my_footer">
<?php
$beginYear = $basic['begin_year'];
$message = $basic['message'];
$year = (date('Y') == $beginYear) ? $beginYear : $beginYear . '–' . date('Y');
$msg = 'Copyright © ' . $year . ' ' . $message;
?>
<div class="col"><?= $msg ?></div>
</footer>
</div>
<script src="/js/bootstrap.bundle.min.js"></script>
<script src="/js/jquery-3.7.1.min.js"></script>
</body>
</html>
%
% cd ~/www/src/Controller
% cp AppController.php ~/files
% vi AppController.php
% cat AppController.php
<?php
declare(strict_types=1);
/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @since 0.2.9
* @license https://opensource.org/licenses/mit-license.php MIT License
*/
namespace App\Controller;
use Cake\Controller\Controller;
use Cake\Http\Session;
use Cake\Http\Response;
use App\Model\BasicModel;
/**
* Application Controller
*
* Add your application-wide methods in the class below, your controllers
* will inherit them.
*
* @link https://book.cakephp.org/5/en/controllers.html#the-app-controller
*/
class AppController extends Controller
{
protected $session;
protected $get;
protected $post;
private $Basic;
/**
* Initialization hook method.
*
* Use this method to add common initialization code like loading components.
*
* e.g. `$this->loadComponent('FormProtection');`
*
* @return void
*/
public function initialize(): void
{
parent::initialize();
$this->Basic = new BasicModel();
$this->loadComponent('Flash');
/*
* Enable the following component for recommended CakePHP form protection settings.
* see https://book.cakephp.org/5/en/controllers/components/form-protection.html
*/
//$this->loadComponent('FormProtection');
$this->session = $this->getRequest()->getSession();
if ($this->getRequest()->is('get')) {
$this->get = $this->getRequest()->getQuery();
} else {
$this->get = [];
}
if ($this->getRequest()->is('post')) {
$this->post = $this->getRequest()->getData();
} else {
$this->post = [];
}
$basic = $this->Basic->getBasicInfo();
$this->session->write('basic', $basic);
$this->set('basic', $basic);
}
public function response(string $str): object
{
$response = new Response();
$response = $response->withType('text/plain');
$response = $response->withStringBody($str);
return $response;
}
}
%
以下のMVC3ファイルを作成し、ルーティング(~/www/config/routes.php)を設定する。
% cd ~/www/src/Model
% vi TopModel.php
% cat TopModel.php
<?php
declare(strict_types=1);
namespace App\Model;
/**
* Top Model
*/
class TopModel extends AppModel
{
// このメソッドは使っていながサンプルとして用意しています。
public function getCopyrightInfo() {
$this->connect();
$sql = "SELECT `begin_year`, `message`"
. " FROM `c_copyright`"
;
$rec = $this->getRecord($sql);
$this->close();
return (empty($rec[0])) ? [] : $rec[0];
}
}
%
% cd ~/www/templates
% mkdir Top
% cd Top
% vi index.php
% cat index.php
<div class="row">
<div class="col"></div>
<div class="col-auto">
<div>
<h5><a href="#" class="link-dark">half-of-string.com</a>はシステムエンジニア(System Engineer)の為になるサイトを目指しています。</h5>
</div>
<div style="height: 20px;"> </div>
..... 以下、省略 .....
%
% cd ~/www/src/Controller
% vi TopController.php
% cat TopController.php
<?php
declare(strict_types=1);
namespace App\Controller;
use App\Model\TopModel;
/**
* Top Controller
*/
class TopController extends AppController
{
private $_top;
public function initialize(): void
{
parent::initialize();
$this->_top = new TopModel();
}
public function index()
{
$this->set('header_message', 'half-of-string.com は SE支援サイト です。');
//$copyright = $this->_top->getCopyrightInfo();
//applog($copyright);
//$this->session->write('copyright', $copyright);
}
}
%
% cd ~/www/config
% cp routes.php ~/files
% vi routes.php
% diff ~/files/routes.php routes.php
58c58
< $builder->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']);
---
> $builder->connect('/', ['controller' => 'Top', 'action' => 'index']);
%
WEBブラウザで確認。https://half-of-string.com