staticが理解できない(調査メモ)

こんばんは、フロントエンドエンジニアだけど最近PHPもはじめてみたよ!な有村です。
みなさんはJSで文字列連結しようとして、「’hoge’.’fuga’」って書いたことはありませんか?世界観ごっちゃになりますよね。

さて今日のテーマはstaticが理解できないです。
以前原田さんの記事にstaticメソッドの使い方が載っていたので、最近それを参考にしてみたんですけど、そもそもstaticとそうじゃないメソッドって何が違うの?って疑問が浮かんできたんです。
私は業務でSmartyを使うので、Smarty functionを作ることがあるのですが、そのときに既存のメソッドを使おうとする場合、newしなければいけないのか、::で呼び出していいのかが分からなくて。
本音としては「インスタンス化するのめんどくせぇ、全部staticで書いたら何がいけないんや!」なんですけど。

そこで調べてみました。メモ。

・static … インスタンス化(new)しないので、初期化がされない。初期化がされないということは、メソッド内の値を保持し続ける。
じゃあAさんとBさんが同じページにアクセスしたりして、同じメソッドを呼び出した場合は、同じ値を参照することになるのか?という疑問が。
これについては、サーバにリクエストが飛んだらその時点で初期化が行われるため、Aさんのリクエスト処理でBさんの処理の値を読んでしまった!ってことはない、らしい。

てことは、staticの使いどころって、メンバ変数とか初期化処理に左右されないメソッドの時なんでしょうか?
引数で値を渡して中で処理するだけ〜とか?

ちなみに今日、PHPに詳しい先輩に上記の認識を確認してみたところ、「う〜ん、違う^^^^」と一蹴されました。
そんなん言われても分からんものは分からんので、ひとまずここで今回の記録はとどめておきます。

それでは、今日はこのへんで。

原則を知る ーDRYー

こんばんは、原田です。

さっき地元の知り合いから電話がきて、地元に帰りたくなりました。はい。

 

 

最近、上司に「どれが良い実装で、どれが悪い実装なのかが分からない」と相談しました。

すると、「原則を知るといい。」という助言を頂きました。

原則  …特別な場合は別として、一般に適用される根本的な法則。

確かに、原則を知ることは、いいコードが分かる導きになるかもしれないと思い、これからちょいちょい原則を書いていこうと思います!!!

 

ではでは、

今日の原則は〜・・・・

DRY

です。

乾燥という意味ではありません。(知らなかったのは私だけですかね?)

DRY(Don’t  Repeat Yourself)

重複を防ぐ考え方。

Single Source of truthとも言うそうです。

 

なぜ重複を防いだ方が良いのか?

重複が多い→変更時に変更箇所が増える→時間がかかる

情報量が多い→明確でない→不一致が生じる可能性がある

という点があるからだそうです。

 

ということで、今後はまとめることができたり、同じような実装が複数ある場合は、関数化したりしてDRYに努めようと思います。

暗黙の型変換

久しぶりです!原田です!

サボってました!すいません!

 

さてさて「暗黙の型変換」ってありますよね、忘れると怖いんで殴り書きします。

これって、PHPだけかと思ってたらSQLもあるらしいです!調べたらまた書きまーす。

 

$a == $b って型変換をした後に、等しいかどうかを判断してるんです。

$a != $b、$a <> $bも型変換後に比較をしているそうです。

↑ switch 文にも当てはまります!

※ === あるいは !== による比較では型変換はしない!型も比較するためです。

 

 

具体的に考えると、、、

比較対象に文字列があると、文字列を数値に変換された後、比較を行うそうです。

$str = ‘string’;      //文字列→数値に変換 (int)”test”; →0(ゼロ)

$num = 0;

if ( $str == $num ) {

echo ‘true’;    //まさかのtrueとなる!

} else {

echo ‘false’;  //falseになると思いきやならない。

}

文字列と数値の比較って思わぬ結果を招く危険があるんですね。

型意識があまりなかったので、一つ一つの型をちゃんとみようと思いました。

 

 

 

 

デリミタ、エスケープ、正規表現・・・。

どうも原田です。

Smartyを触っていたので、今回はSmartyネタというか、PHPネタです!

SmartyでPHP関数使えますよね。(最近知ったw)

 

PHPもSmartyも世の中も何もかもわからない私にとって、

preg_matchを使う機会に遭遇いたしまして、何で第一引数を「/」(スラッシユ)で囲ってんの?って思いまして、、、、

さらに、この中でよく意味のわからない記号を使っておる!!→正規表現

 

phpmanualによりますと、、、

preg_match($pattern,  $input_word);

$pattern=’/^abc/’; みたいなんがきます。

 

ポイント

$pattern=’/(探したい言葉)/‘;

「^」は先頭、ちなみに末尾は「$」、「*」は直前の文字が1個以上連続。他には「/」や「.」があります。【正規表現】

 

囲ってる「/」をデリミタというそうですね。

このデリミタの中に、探したいワードを書くわけですが、もし「/」を探したい時どうしますか?

→「\」(エスケープ)ですね!

こんな感じ preg_match(‘/ \/ /’, $input_word);

何を探したいのかがよくわからず、見にくいですよね!!!

 

こんな時はデリミタの変更をすると便利です!

使えるデリミタは「#」や「+」、「%」などいっぱいあるんです。

なので、さっき見にくかったやつも、、

preg_match(‘# \/ #’, $input_word);

うーん ・・・見にくいですが、ごちゃつきが減りましたよね!

こんな感じで読みやすくするのも、大切だなあと思いましたとさ。ちゃんちゃん。

 

 

ちなみに、わたしは正規表現がよくわからず、

どうエスケープしたらいいのかよくわからない!

そんな時はー・・・・。

preg_quote()!!

正規表現をクオート(エスケープ)してくれる関数なのです!

これ超便利って思う。

preg_quote (‘エスケープしたいもの’, ‘デリミタ’);

使うとこんな、感じ。

 

<?php

$str = ‘This /is $100.’

$res = preg_quote($str, ‘/’);

echo $res   //    This \/is \$100\.を返します

 

よって、preg_matchでパターンとして使う時は、preg_quoteから得た結果をそのままつっこんで、

preg_match(‘/ This \/is \$100\. /’,  $input_word);

このように、正規表現とか、デリミタとか、エスケープどこでしたらええんのん

っって時使えます!!!!

->メソッド()と::メソッド()の違いってなんだ?《PHP編》

どうも原田です。

今週末2日間のフェスに行くため、日焼けしてきますの原田です。

来年の目標はFUJIROCKに行くことです!

 

本題ですが、この前コードを書いてて、ふとというか、

毎回わかなんないけど、曖昧なままにしていたこと(タイトル通り)について調べました。

 

調べていくと、すっごいわかりました!一瞬。以上

この報告と共に終わりたいところですが、忘れないうちに書いておこう。

 

>>$this->メソッド()とself::メソッド()の違い

■self::
自クラスのプロパティ、及びメソッドへの静的(static)アクセスを行う。
クラス外からの呼び出しでも、呼び出し先がpublicならアクセスできる!(その時はクラス名::)
■$this
自分自身のオブジェクトを指す。疑似変数

 

>>そこで新たな疑問が・・・静的(static)メソッドとは?

・クラスの中のプロパティもしくはメソッドを static として宣言することで、クラスのインスタンス化($obj = new class();)せずにアクセスできる!
<?php
class Example
{
    public $param1 'NOT staticなプロパティ';
    public static $param2 'staticなプロパティ';
    public static function test()
    {
        returnself::$param2;
    }
    public  static  function test_error() {
        return $this->param2;
    }
}
//クラス名Exampleのインスタンス化
$obj=new Example();
//$param1はstaticなプロパティではないため、インスタンスしたクラスを’->’でアクセス可能
$res1=$obj->param1;
//$param2はstaticなプロパティのため、インスタンス化せずに簡単に’::’でアクセス可能
$res2=Example::$param2;
$res3=Example::test();
逆に、
・static なプロパティは、インスタンス化されたクラスオブジェクトから アクセスすることはできない(static なメソッドにはアクセスできます)。
・static プロパティは、矢印演算子 -> によりオブジェクトからアクセス することはできない。
//クラス名Exampleのインスタンス化
$obj=new Example();
//$param2はstaticなプロパティのため、インスタンス化されたクラスオブジェクトから ‘->’でのアクセス不可
$res1=$obj->param2;
//$param1はstaticなプロパティではないため、クラスのインスタンス化無しに’::’ではアクセスできない。
$res2=Example::$param1;
//例外
//test()はstaticなメソッドのため、インスタンス化されたクラスオブジェクトからのアクセス可能
$res3=$obj->test();

・疑似変数 $this は、 static として宣言されたメソッドの内部から利用することはできない。

class Example
{
    public $param1 'NOT staticなプロパティ';
    public static $param2 'staticなプロパティ';

   public  static  function  test_error()

    {

        return $this->param2;

    }
}
ほうほう!!!!!
PHPを触り始めて早約3ヶ月、6月では意味不明だったことも飲み込める気がしてきた、そんな夏。