wp-config.php が反映されない

解決したので記事書きます。
原因は簡単(BOM)だったのですが、見落とす可能性は高そうです。

現象

WordPressの設定ファイルである「wp-config.php」を編集したが、変更内容が反映されない。

試したこと

  1. 適当に検索してみたところ、編集範囲の外に記述していないかなどが出てきたが、今回は関係が無かった。(権限関係でそもそも編集できないなども出てきたが、今回の現象とは無関係)
  2. 自分が編集しているファイル以外のファイルがロードされている可能性を考えて $ find / -name "wp-config.php" したが、他に同一名のファイルはサーバ上に無かった。
  3. 何かしらブラウザのキャッシュが悪さしている可能性を考えてキャッシュを消してページを読み込んだが、変更内容は反映されていなかった。
  4. 公式のリファレンスを参照してみたが、有用な情報はなかった。
  5. Google is GOD 救済を得た。

解決

適当にググってこちらの情報に行き着いた。

原因は、TeraPadで編集して、保存がUTF-8のBOM無じゃなかったから。
BOM無という言葉はないが、UTF-8Nがそれらしい。未確認だけど、試したら解決した。

WordPress wp-config.phpが反映しない | weblogs

vimで適当に編集していたのでBOMとか全く気にしていなかった。
こんなところでもBOMに苦しめられるとは思わなんだ。

vimでBOMの有無を確認したところ、見事にbomが付いていたので消し飛ばして解決。

※vimにて

:set bomb?
> bomb

:set nobomb
:set bomb?
> nobomb

参考: VimでのBOMの取り扱い – Qiita

wp-configの中にUTF-8のBOM無しで保存するようにと、かなりわかりやすい注意書きがあったので、そこが目に入っていれば気がついたかもしれない。

nginxでbasic認証してみた

1.動機

・リンクを知られていると誰でも見れるのは少し気持ち悪いなと感じたため

2.環境

・ubuntu 20.04.1 LTS(64bit)
 visualboxの仮想環境
・nginx 1.18.0
・apache2-utils
 →htpasswd作成用

3.手順

① htpasswdで認証情報を作成
  →下記コマンド実行後、設定パスワードを入力

$htpasswd -c (パス)/.htpasswd (ユーザー名)

② ①で設定したファイルをnginxで読み込む


  ・/devにアクセスした際に認証をかけたい場合、
   /etc/nginx/sites-availavle/defaultを下のように編集
  
  location /dev {
    auth_basic “認証画面で表示する文言”;
    auth_basic_user_fire ①で設定したパス;
    …
  }

③ nginxの設定再読み込み

$nginx -s reload
$service nginx restart

④ 完成
  ①で設定したユーザー名とパスワードを入力してログイン

Termiusでkeepaliveを設定する

Putty? TeraTerm? 時代はTermius🌊

Termiusでkeepaliveを設定するのに少し手間取ったので備忘録として書いておきます。

□設定方法

①Termiusを開き、左上のハンバーガー(っぽい)メニューを選択

②メニュー内の「 Terminal 」を選択

③メニュー下部の「 Keepalive Interval 」を設定
※ミリ秒で設定するので、20秒であれば、20000と入力する必要あり💦

以上で設定完了です!

余談ですが、ダークモードは①のハンバーガーメニュー下部にあります✨

Effective Javaを読みました

Javaを扱っている人のバイブル的な本ですね。

今まで読んだ本について各項目について書いておりましたが、Effective Javaについては量が多いのでざっくりとした感想だけ書きたいと思います。

第3版を読みました。第2版と比較しましたが、ラムダとストリームという章が追加され、その他の章は大きくは変わってなさそうな印象でした。第2版はもちろん読んでません。

◾️追加された項目
第2章 オブジェクトの生成と消滅
 項目5 資源を直接結び付けるよりも依存性注入を選ぶ
 項目8  ファイナライザとクリーナーを避ける
 項目9 try-finallyよりもtry-with-resourcesを選ぶ

第4章 クラスとインターフェース
 項目21 将来のためにインターフェースを設計する
 項目25 ソースファイルを単一のトップレベルのクラスに限定する

第7章 ラムダとストリーム(※全て追加)
 項目42 無名クラスよりもラムダを選ぶ
 項目43 ラムダよりもメソッド参照を選ぶ
 項目44 標準の関数型インターフェースを使う
 項目45 ストリームを注意して使う
 項目46 ストリームで副作用のない関数を選ぶ
 項目47 戻り値型としてStreamよりもCollectionを選ぶ
 項目48 ストリームを並列化することは注意を払う

第8章 メソッド
 項目55 オプショナルを注意して返す

第11章 並行性
 項目80 スレッドよりもエグゼキュータ、タスク、ストリームを選ぶ

第12章 シリアライズ
 項目85 Javaのシリアライズよりも代替手段を選ぶ

◾️感想
正直、Javaを軽くしか触っていない自分にとっては難しいところが多々ある本でした。
といっても、メソッドやプログラミング一般などは比較的な簡単な項目があったりしたので、全部が難しいわけではないです。

この本に関して初心者に読んでほしい、初心者には向かないなど色々な意見がありますが、自分は初心者の人に関しては、読み方を気をつければ読んだほうがいいかと思います。
罠にハマらないような書き方、どうすると罠にはまってしまうのかなども記載されているため、早めに直しておきたい項目が多々あるからです。
読み方としては項目毎に軽く2ページほど読んで、理解できそうかどうか、あるいは頑張れば理解できそうだったらしっかりその項目を読んで、わからなかったところは時間が経ってから読み直すといったやり方がいいと思います。
デザインパターンを知らないのに解説もされていないデザインパターンについて言及されている項目が理解できるはずがないと思います。
そういうのが多くある場合、挫折すると思うのでここは後回しでいいと割り切っていくのがいいかと思います。
自分も読んでいて心折れかけそうなときがありました。
ですので、わからなかったときに何を勉強しておくとわかるようになるのかをメモしておいてそれについて勉強してから読むぐらいの認識でいいと思います。

内容についてですが、凄く勉強になりました。
例えば 第2章のすべてのオブジェクトに共通のメソッドについてはお恥ずかしながらJava標準でのメソッドをオーバーライドをするという発想が皆無だったのでtoStringをオーバーライドするなどは新鮮でした。
第5章のジェネリック型はよく使ってますがやっぱり便利だと感じます。ArrayListがPHPにも欲しい。
第6章のenum、第7章のラムダとストリーム、第11章の並行性はぜひ使いこなしたいです。
誤解かもしれないですが継承はもうあまり使わない方がよかったりするのかな?最近はis-aよりhas-a傾向強い気がします。

この本に関しては手元に置いておいて必要な時に何度も読み返したいと思います。

Prototypeパターン

Prptotypeパターンは生成に関するデザインパターンの1つです。 通常はnewしてインスタンスを生成しますが、Prototypeでは既存のインスタンスをコピー(clone)して新しいインスタンスを生成します。

メリット
新しいインスタンスを作成する複雑さを、クライアントから隠蔽する。
型のわからないオブジェクトの生成を行うという選択肢を、クライアントに提供する。
環境においてはオブジェクトのコピーの方が新しいオブジェクトを作成するよりも有効である可能性がある(ソースコードの管理等)。

デメリット
コピーを作る事で物事が複雑になる場合がある(これについては追々書いてみたい)。

Head First デザインパターンでモンスターを作るクラス図があったのでそれを参考に中身だけ書いてみたいと思います。
単純にモンスターをコピーできるようにするのと、ゲームを楽しむユーザーがモンスターのレベルとHPを変更できるようにしていきます。

・Monster.php

<?php
abstract class Monster
{
    private int $id; // 1種類につき与えられるモンスターのid
    private string $name;
    protected int $level;
    protected int $hp;
    private string $category;
    private bool $copied; // コピーされたものかどうか

    public function __construct(int $id, string $name, int $level, int $hp, string $category)
    {
        $this->id = $id;
        $this->name = $name;
        $this->level = $level;
        $this->hp = $hp;
        $this->category = $category;
        $this->copied = false;
    }

    abstract protected function __clone();

    public function newInstance(): \Monster
    {
        return clone $this;
    }

    public function getId(): int
    {
        return $this->id;
    }

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

    public function getLevel(): int
    {
        return $this->level;
    }

    public function getHp(): int
    {
        return $this->hp;
    }

    public function getCategory(): string
    {
        return $this->category;
    }

    public function getCaller(): string
    {
        return $this->caller;
    }

    protected function copied(bool $copied): void
    {
        $this->copied = $copied;
    }

}

ユーザー側で値を変更できないモンスター
・WellKnownMonster.php

<?php
require_once 'Monster.php';

class WellKnownMonster extends Monster
{

    protected function __clone()
    {
        $this->copied(true);
    }

}

ユーザー側でlevelとhpを変更できるモンスター
・DynamicPlayerGeneratedMonster.php

<?php
require_once 'Monster.php';

class DynamicPlayerGeneratedMonster extends Monster
{
    protected function __clone() {
        $this->copied(true);
    }

    public function setLevel(int $level): void
    {
        $this->level = $level;
    }

    public function setHp(int $hp): void
    {
        $this->hp = $hp;
    }
}

・MonsterRegistry.php

<?php

class MonsterRegistry
{
    private array $registered;

    public function register(Monster $monster): void
    {
        $this->registered[$monster->getId()] = $monster;
    }

    public function getMonster(int $id){
        return $this->registered[$id]->newInstance();
    }
}

・ index.php

<?php
require_once 'MonsterRegistry.php';
require_once 'WellKnownMonster.php';
require_once 'DynamicPlayerGeneratedMonster.php';

$monsterRegistry = new MonsterRegistry();
$monster1 = new WellKnownMonster(1, 'ゴブリン', 4, 12, 'ゴブリン');
$monsterRegistry->register($monster1);
$monsterCopy1 = $monsterRegistry->getMonster($monster1->getId());

var_dump($monster1);
var_dump($monsterCopy1);

$monster2 = new DynamicPlayerGeneratedMonster(37, 'アイスボム', 24, 400, 'ボム');
$monsterRegistry->register($monster2);
$monsterCopy2 = $monsterRegistry->getMonster($monster2->getId());
$monsterCopy2->setLevel(99);
$monsterCopy2->setHp(9999);

var_dump($monster2);
var_dump($monsterCopy2);

コピー元となるモンスターはDBに入れそうなものですが…。 その場合は引っ張ってきてインスタンス化して必要であればコピーしていくといった方法で使うといいかな?って思います。

(参考)
Head Firstデザインパターン ―頭とからだで覚えるデザインパターンの基本
2005/12/2
Eric Freeman (著), Elisabeth Freeman (著), Kathy Sierra (著), Bert Bates (著), 佐藤 直生 (監訳), 木下 哲也 (翻訳), 有限会社 福龍興業 (翻訳)
13章 付録:残りのパターン