PHPの和暦→西暦

ini_set('display_errors', "On");

function seireki($wareki_year){

	$wareki_year = str_replace("元年", "1年", mb_convert_kana($wareki_year, "n"));

	if(preg_match('!^(明治|大正|昭和|平成|令和)([0-9]+)年$!', $wareki_year, $matches)){

		$era_name = $matches[1];
		$year = intval($matches[2]);

		if($era_name === "明治"){
			$year += 1867;
		} else if($era_name === "大正"){
			$year += 1911;
		} else if($era_name === "昭和"){
			$year += 1925;
		} else if($era_name === "平成"){
			$year += 1988;
		} else if($era_name === "令和"){
			$year += 2018;
		}

		return $year . "年";
	}
	return null;
}
echo seireki("平成元年");

$ php index.php
1989年

preg_matchで元号と年を分割する訳ね。なるほど、ロジックはわかった。

PHPの西暦→和暦変換

ini_set('display_errors', "On");

function wareki($year){

	$eras = array(
		array('year' => 2018, "name" => "令和"),
		array('year' => 1988, "name" => "平成"),
		array('year' => 1925, "name" => "昭和"),
		array('year' => 1911, "name" => "大正"),
		array('year' => 1867, "name" => "明治")
	);

	foreach($eras as $era){

		$base_year = $era['year'];
		$era_name = $era['name'];

		if($year > $base_year){
			$era_year = $year - $base_year;

			if($era_year === 1){
				return $era_name . "元年";
			}

			return $era_name . $era_year ."年";
		}
	}
	return null;
}

echo wareki(1989);

$ php index.php
平成元

なるほど、これは凄い

数字のカンマ、カンマ削除

$num = 100000;
echo number_format($num);

$ php index.php
100,000

カンマ除去

$num = "100,000";
echo str_replace(",", "", $num);

$ php index.php
100000

半角カナ→全角カナ

$str = "キャピタルメディア";
echo mb_convert_kana($str, "KV");

$ php index.php
キャピタルメディア

全角カナ→半角カナ

$str = "キャピタルメディア";
echo mb_convert_kana($str, "kV");

$ php index.php
キャピタルメディアva

カナ以外にも、数字、英字、スペースも変換できる。なるほど。

日付変換

$date = "20230321";
echo date("Y/m/d", strtotime($date));

php index.php
2023/03/21

$date = "20230321";
echo date("Y年m月d日", strtotime($date));

$ php index.php
2023年03月21日

ゼロパディング、前ゼロ除去

ゼロパディング

$num = 7;
$num2 = sprintf('%03d', $num);
echo $num2;

$ php index.php
007

前ゼロ除去
L intにキャスト

$str = "00070";
$str = (int)$str;
echo $str;

ltrim

$str = "00070";
$str = ltrim($str, 0);
echo $str;

php 文字列の結合

$intermediate = "-";
$var1 = "いつかは";
$var2 = "ゆかし";
$joined = $var1 . $intermediate . $var2;
echo $joined;

$ php index.php
いつかは-ゆかし

php 真偽値

$var = true;
if($var){
	echo "成功";
} else {
	echo "失敗";
}

$ php index.php
成功

$var = false;
if($var){
	echo "成功";
} else {
	echo "失敗";
}

$ php index.php
失敗

ifでtrue, falseを判定できる

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){
		
	}
}

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();
}

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();

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

cakephp4.xに慣れよう3 Authentication

Installing Authentication Plugin
$ php composer.phar require “cakephp/authentication:^2.0”

Adding Password Hashing
$ bin/cake bake all users

src/Model/Entity/User.php

namespace App\Model\Entity;

use Authentication\PasswordHasher\DefaultPasswordHasher;
use Cake\ORM\Entity;

class User extends Entity {
    protected function _setPassword(string): ?string {
        if(strlen($password) > 0 ){
            return (new DefaultPasswordHasher())->hash($password);
        }
    }
}

Adding Login
// src/Application.php

    public function getAuthenticationService(ServiceRequestInterface $request){
        $authenticationService = new AuthenticationService([
            'unauthenticatedRedirect' => Router::url('/users/login'),
            'queryParam' => 'redirect',
        ])

        $authenticationService->loadIdentifier('Authentication.Password', [
            'fields' => [
                'username' => 'email',
                'password' => 'password',
            ]
        ]);

        $authenticationService->loadAuthenticator('Authentication.Session');
        $authenticationService->loadAuthenticator('Authentication.Form', [
            'fields' => [
                'username' => 'email',
                'password' => 'password',
            ],
            'loginUrl' => Router::url('/users/login'),
        ]);
        return $authenticationService;
    }

// src/Controller/AppController.php

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

UsersController

    public function beforeFilter(\Cake\Event\EventInterface $event){
        parent::beforeFilter($event);
        $this->Authentication->addUnauthenticatedAction(['login']);
    }

    public function login(){
        $this->request->allowMethod(['get', 'post']);
        $request = $this->Authentication->getResult();
        if($result && $result->isValid()){
            $redirect = $this->request->getQuery('redirect', [
                'controller' => 'Articles',
                'action' => 'index',
            ]);
            return $this->redirect($redirect);
        }
        if($this->request->is('post') && !$result->isValid()){
            $this->Flash->error(__('Invalid username or password'));
        }
    }

// /templates/Users/login.php

<div class="users form">
	<?= $this->Flash->render() ?>
	<h3>Login</h3>
	<?= $this->Form->create() ?>
	<fieldset>
		<legend><?= __('Please enter your username and password') ?></legend>
			<?= $this->Form->control('email', ['required'=> true]) ?>
			<?= $this->Form->control('password', ['required'=> true]) ?>
	</fieldset>
	<?= $this->Form->submit(__('Login')); ?>
	<?= $this->Form->end() ?>

	<?= $this->Html->link("Add User", ['action' => 'add']) ?>
</div>

// in src/Controller/AppController.php

    public function beforeFilter(\Cake\Event\EventInterface $event){
        parent::beforeFilter($event);
        $this->Authentication->addUnauthenticatedActions(['index', 'view']);
    }

Logout

    public function logout(){
        $result  = $this->Authentication->getResult();
        if($result && $result->isValid()){
            $this->Authentication->logout();
            return $this->redirect(['controller'=> 'Users', 'action'=> 'login']);
        }
    }

なるほど、CakePHPは人気に翳りがあるので舐めてましてが、自分がアホでしたね。かなり色々勉強しないと追いつかないほど先を行ってます。