CakePHPのbeforefilter

beforeFilterはControllerで使用するコールバックメソッドで、主に共通化したい処理を記述
メソッドの中身よりも先に実行される

function beforeFilter(Event $event){
	処理...
}

sample
cake/src/Controller/BeforeController.php

namespace App\Controller;
use App\Controller\AppController;
use Cake\Event\Event;

class BeforeController extends AppController {
	public $text = "samurai";

	public function beforeFilter(Event $event){
		$this->text = 'hogehoge';
	}

	public function index(){
		this->set('text', $this->text);
	}
}

beforeFilterははじめに呼び出されるため、Authなどのユーザ認証やエラー内容の設定に適している。

	public function beforeFilter(Event $event){
		$this->Auth->config('authenticate', ['Form']);

		$this->Auth->config('authenticate', [
			'Basic' => ['userModel' => 'Members'],
			'Form' => ['userModel' => 'Members'],
		]);
	}

なるほど、どのタイミングで処理を行うかってことね。

implements

interfaceとは: そのクラスに実装しないといけないメソッドをまとめたパッケージのようなもの。複数ファイルを作成する際に決まったメソッドを実装してほしい時に使える

interface Template {
	public function setVariable($name, $var);
	public function getHtml($template);
}

class Hoge implements Template {
	public function setVariable($name, $var){

	}

	public function getHtml($template){
		
	}
}

PostgreSQL innerjoinとleftjoin

テーブルとテストデータ作成
CREATE TABLE companies(
id bigint primary key,
name varchar(50) NOT NULL,
tel varchar(50)
);

CREATE TABLE employees(
id bigint primary key,
company_id bigint,
name varchar(50) NOT NULL,
age integer,
FOREIGN KEY (company_id) references companies(id)
);

INSERT INTO companies(id, name, tel) VALUES
(1, ‘株式会社ほげ’, ’00-0000-0000′),
(2, ‘株式会社ふが’, ’00-0000-1111′),
(3, ‘株式会社ぴよ’, ’00-0000-2222′);

INSERT INTO employees(id, company_id, name, age) VALUES
(1, 1, ‘テスト太郎’, 25),
(2, 1, ‘テスト次郎’, 20),
(3, 2, ‘テスト三郎’, 30),
(4, null, ‘テスト五郎’, 40);

### 内部結合(inner join)
結合条件に一致するレコードだけ表示
testdb=# SELECT
testdb-# e.id AS employee_id,
testdb-# e.name AS employee_name,
testdb-# c.id AS company_id,
testdb-# c.name AS company_name
testdb-# FROM employees e
testdb-# JOIN companies c ON c.id = e.company_id;
employee_id | employee_name | company_id | company_name
————-+—————+————+————–
1 | テスト太郎 | 1 | 株式会社ほげ
2 | テスト次郎 | 1 | 株式会社ほげ
3 | テスト三郎 | 2 | 株式会社ふが

### LEFT JOIN
左外部結合。左テーブルを全て表示し、結合条件に一致しない右テーブルはNULLとして結合
testdb=# SELECT
testdb-# e.id AS employee_id,
testdb-# e.name AS employee_name,
testdb-# c.id AS company_id,
testdb-# c.name AS company_name
testdb-# FROM employees e
testdb-# LEFT JOIN companies c ON c.id = e.company_id;
employee_id | employee_name | company_id | company_name
————-+—————+————+————–
1 | テスト太郎 | 1 | 株式会社ほげ
2 | テスト次郎 | 1 | 株式会社ほげ
3 | テスト三郎 | 2 | 株式会社ふが
4 | テスト五郎 | |

### LIGHT JOIN
testdb=# SELECT
testdb-# e.id AS employee_id,
testdb-# e.name AS employee_name,
testdb-# c.id AS company_id,
testdb-# c.name AS company_name
testdb-# FROM employees e
testdb-# RIGHT JOIN companies c ON c.id = e.company_id;
employee_id | employee_name | company_id | company_name
————-+—————+————+————–
1 | テスト太郎 | 1 | 株式会社ほげ
2 | テスト次郎 | 1 | 株式会社ほげ
3 | テスト三郎 | 2 | 株式会社ふが
| | 3 | 株式会社ぴよ
(4 rows)

なるほど、これは勉強になる。

PHPのエラーと例外処理

ini_set('display_errors', 1);

$fd = fopen("c:/temp/abc.txt", "r");
echo "継続処理";

a();
echo "継続処理";

$ php index.php

Warning: fopen(c:/temp/abc.txt): failed to open stream: No such file or directory in /home/vagrant/dev/test/index.php on line 5
継続処理
Fatal error: Uncaught Error: Call to undefined function a() in /home/vagrant/dev/test/index.php:8
Stack trace:
#0 {main}
thrown in /home/vagrant/dev/test/index.php on line 8

### set_error_handler

set_error_handler(function($errno, $errstr, $errfile, $errline){
	print("エラーが発生しました。$errno, $errstr <br>");
});

$fd = fopen("c:/temp/abc.txt", "r");

$ php index.php
エラーが発生しました。2, fopen(c:/temp/abc.txt): failed to open stream: No such file or directory

### Exception
例外が発生しそうな処理には、try, catch, finallyを使う

set_error_handler(function($errno, $errstr, $errfile, $errline) {
    if (!(error_reporting() & $errno)) {
        return;
    }
    throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
});


try {
	$fd = fopen("c:/temp/abc.txt", "r");	
} catch(Exception $e){
	echo "例外が発生しました。".$e->getMessage();
}

Rockey Linux

OSS Linux distribution
RedHat Enterprise Linux8のクローンとして開発されており、CentOS/AlmaLinuxと変更点はない
yumリポジトリが提供、コミュニティ中心の発展
Azureでの配布がない、セキュアブート対応もない
ミラーリポジトリはAlmaLinuxの方が多い

現場ではRockey Linuxの方が採用が多いみたい

Gentoo Linux と Alma Linux

### Gentoo Linux
Gentoo Linuxは上級者向けLinux distribution
Portageと呼ばれるパッケージ管理システム
RPMやdebと異なりソースコードからソフトウェアのインストールを行う
ebuildというスクリプトがあり、これに従ってソースコードのコンパイル、インストールなどを行う
-> 自由度の高いシステム構築を行うことができる。コンパイル時にもに設定できる機能を切り替えができる
カスタマイズ性が高いが、それゆえに難易度が高い。パッケージの理解がないと使いこなすのが難しい

### AlmaLinux
CentOS8.0の後継
yumリポジトリでのアップデート情報が提供されている
RockeyLinuxよりもリリースが早く、クラウド対応なども進んでいる
乗り換えOSとしては有力、開発スピードが速い

WEB S@T

Webサイトが改ざんされていないかを監視
24時間自動で定期監視し、改ざんを検知した際は登録されたメールアドレスへ自動通知サービス
更新か改ざんかを見分けて、改ざんの場合はメール通知

なるほど、そこまで用途の拡張性はなさそうかな

PHPの擬似変数this

PHPの擬似変数thisはクラスのインスタンス自信を指す

class Fruits {

	private $name = "";

	public function setName($name){
		$this->name = $name;
	}

	public function getName(){
		return $this->name;
	}

	public function getNameLocal(){
		$name = "orange";
		return $name;
	}
}

$fruits = new Fruits();

$fruits->setName("apple");

echo $fruits->getName(). "\n";
echo $fruits->getNameLocal();

プロパティの中にアクセスできるようにすることなのね。

【CakePHP】Authorization Plugin

$ php composer.phar require “cakephp/authorization:^2.0”

bootstrap() method in src/Application.php:
src/Application.php

        $this->addPlugin('Authorization');

Enabling the Authorization Plugin

use Authorization\AuthorizationService;
use Authorization\AuthorizationServiceInterface;
use Authorization\AuthorizationServiceProviderInterface;
use Authorization\Middleware\AuthorizationMiddleware;
use Authorization\Policy\OrmResolver;
            ->add(new AuthorizationMiddleware($this));
    public function getAuthorizationService(ServerRequestInterface $request): AuthorizationServiceInterface {
        $resolver = new OrmResolver();

        return new AuthorizationService($resolver);
    }

lets add the AuthorizationComponent to AppController. In src/Controller/AppController.php add the following to the initialize() method.

    public function initialize(): void
    {
        parent::initialize();
        $this->loadComponent('Flash');
        $this->loadComponent('Authentication.Authentication');
        $this->loadComponent('Authorization.Autorization');

        $this->loadComponent('RequestHandler');
        $this->loadComponent('Flash');
    }

Lastly we’ll mark the add, login, and logout actions as not requiring authorization by adding the following to src/Controller/UsersController.php

        $this->Authorization->skipAuthorization();

Creating our First Policy
$ bin/cake bake policy –type entity Article

src/Policy/ArticlePolicy.php

namespace App\Policy;

use App\Model\Entity\Article;
use Authorization\IdentityInterface;

class ArticlePolicy {

	public function canAdd(IdentityInterface $user, Article $article){
		return true;
	}

	public function canEdit(IdentityInterface $user, Article $article){
		return $this->isAuthor($user, $article);
	}

	public function canDelete(IdentityInterface $user, Article $article){
		return $this->isAuthor($user, $article);
	}

	public function isAuthor(IdentityInterface $user, Article $article){
		return $article->user_id === $user->getIdentifier();
	}
}

src/Controller/ArticlesController.php

    public function add()
    {
        $article = $this->Articles->newEmptyEntity();
        $this->Authorization->authorize($article);

	public function edit($slug) {
		$article = $this->Articles
			->findBySlug($slug)
			->contain('Tags')
			->firstOrFail();
		$this->authorization->authorize($article);

	public function delete($slug)
	{
	    $this->request->allowMethod(['post', 'delete']);

	    $article = $this->Articles->findBySlug($slug)->firstOrFail();
	    $this->Authorization->authorize($article);

add tag, view, index method

$this->Authorization->skipAuthorization();

なるほど、methodの中でAuthorizationを使うか使わないか記述するのね。