Webサイトが改ざんされていないかを監視
24時間自動で定期監視し、改ざんを検知した際は登録されたメールアドレスへ自動通知サービス
更新か改ざんかを見分けて、改ざんの場合はメール通知
なるほど、そこまで用途の拡張性はなさそうかな
随机应变 ABCD: Always Be Coding and … : хороший
Webサイトが改ざんされていないかを監視
24時間自動で定期監視し、改ざんを検知した際は登録されたメールアドレスへ自動通知サービス
更新か改ざんかを見分けて、改ざんの場合はメール通知
なるほど、そこまで用途の拡張性はなさそうかな
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();
プロパティの中にアクセスできるようにすることなのね。
$ 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を使うか使わないか記述するのね。
Pythonファイル(平文ソースコード)をコンパイルするとpycファイルになる。
pythonユーザがpycファイルを作成する必要なし。モジュールとしてインポートされる場合に自動的に作成
元のモジュールが更新されると、次回インポート時にpycファイルも自動的に再作成
マジックナンバーとは、ファイルの種類を識別するため、ファイル先頭に付与する特別なバイト列。Pythonのバージョンごとにpycファイルのマジックナンバーが決まっている。
$ python3
Python 3.8.10 (default, Mar 15 2022, 12:22:08)
[GCC 9.4.0] on linux
Type “help”, “copyright”, “credits” or “license” for more information.
>>> import importlib.util
>>> importlib.util.MAGIC_NUMBER.hex()
‘550d0d0a’
sessionファイルの場所
1. php.iniのsession.save_path
2. php.iniのsys_temp_dir
3. /tmp
今回ubuntuの場所では、/var/lib/php/sessionsに格納されていた。
$ sudo cat sess_t8mk08vtmj3vh29s8rhq4tsh22
hoge|s:4:”hoge”;fuga|s:4:”fuga”;
【セッション名】|s:【セッションのID】:【値】で保存される
session_encodeという関数でエンコードしている
なるほど、基礎的な挙動は理解した。
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は人気に翳りがあるので舐めてましてが、自分がアホでしたね。かなり色々勉強しないと追いつかないほど先を行ってます。
Composerはパッケージ管理以外にオートロードという機能を合わせ持ち、require文を使用しなくてもクラスファイルを読み込むことができる
### require文の使い方
Userクラスを作成する
src/User.php
class User{
protected $name;
public function __construct($name){
$this->name = $name;
}
public function get_user_name(){
return $this->name;
}
}
index.php
require('src/User.php');
$user = new User('taro');
var_dump($user->get_user_name());
composer.json
{
"autoload": {
"psr-4": {
"Test\\": "src"
}
}
}
php composer.phar dump-autoload
/vendor/composer/autoload_psr4.php
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'Test\\' => array($baseDir . '/src'),
);
namespace Test;
class User{
protected $name;
public function __construct($name){
$this->name = $name;
}
public function get_user_name(){
return $this->name;
}
}
なるほど、requireではなく、composerでautoloadできることはわかった。
PSRとはPHP Standard Recommendationsのことで、PHP-FIG(PHP Interop Group)が昨制定しているコーディング規約のこと。PRSにはいくつか種類がある。
PSR-4はAutoloader
ファイルパスからクラスをオートロードするための規約
PSR-0という削除予定の規約もある
\
どのパスにどのクラスを配置するのか仕様を決めたいというのが根にある
psr-0とpsr-4があるってことはわかったが、autoloadの仕組みがよくわからん。require_onceとは違うのね。。。
namespaceは名前空間と呼ばれ、項目をカプセル化するときに使用する
通常、同じファイルに同じクラスや関数名、定数めいが存在することはできないが、名前空間を使用することにより、関連するクラスやインターフェイス、関数、定数などをグループ化することが可能
名前が衝突することを防ぐことができる
namespaceは以下のように記述する
namespace 名前空間名;
ソースコードの一番先頭で宣言する必要があり、namespaceの前にHTMLを記述するとエラーになる
sample1.php
namespace name1;
function getName(){
return "fruit";
}
namespace name2;
function getName(){
return "ore";
}
sample2.php
//phpファイルを読み込む require_once 'sample1.php'; //関数の呼出し echo name1\getName(); echo name2\getName();
$ php sample2.php
fruitore
namespaceを宣言すると、その後に記述した関数はその名前空間の関数に属する
名前空間\関数名とすれば同一の関数を呼び出すことが可能になる
波括弧で指定したい範囲を囲むこともできる
namespace name1 {
function getName(){
return "fruit";
}
}
namespace name2{
function getName(){
return "ore";
}
}
波括弧で囲むと、名前空間の範囲外で命令文を記述することができなくなってしまう
namespace name1 {
function getName(){
return "fruit";
}
}
namespace name2{
function getName(){
return "ore";
}
}
echo "Hello World!";
### useの使い方
useとは名前空間の拡張機能で、外部のエイリアスやその一部を参照したり、クラス・関数・定数などをインポートするときに使用する
namespace asia\japan\tokyo\shibuya;
function getName(){
return "shibuya";
}
namespace asia\japan\tokyo\minato;
function getName(){
return "minato";
}
namespace asia\japan\tokyo\shinagawa;
function getName(){
return "shinagawa";
}
[_code]
require_once "sample1.php";
use asia\japan\tokyo as name;
echo name\shibuya\getName();
echo name\minato\getName();
名前空間のnamespaceとuseはなんとなくわかったが、composer.jsonのpsr-4, psr-0がイマイチよくわからん。。
### ライブラリ側
$ tree
.
├── composer.json
├── src
│ └── Muuu
│ └── Uuuu.php
└── test
/src/Muuu/Uuuu.php
class Dog {
private $name;
public function __construct($name){
$this->name = $name;
}
public function getName(){
return $this->name . "さん!";
}
}
$ git init
$ git add .
$ git commit -m “first commit”
$ git remote add origin
$ git push -u origin master
### プロジェクト側
composer.json
{
"name": "library/test",
"description": "Composer sample project",
"authors": [
{
"name": "hpscript",
"email": "hpscript@gmail.com"
}
],
"type": "project",
"minimum-stability": "dev",
"require": {
"nuuu/muuu": "*"
},
"autoload": {
"psr-4": {"App\\": "src/"}
},
"repositories": {
"nuuu/muuu": {
"type": "vcs",
"url": "https://github.com/hpscript/package.git"
}
}
}
require_once "./vendor/autoload.php";
use App\Muuu\Uuuu;
$dog = new Uuuu::Dog("hoge");
$dog_name = $dog->getName();
echo $dog_name;
名前空間とclassの概念はよくわからん。。。