英文字には大文字と小文字がある。
英大文字⇔英小文字の相互変換ならstrtoupper(), strtolower()関数を使う。


●すべて英小文字変換なら
<?php

$word = 'string';

$lowercase = strtolower($word); // "string"




●すべて英大文字変換なら
<?php

$word = 'string';

$uppercase = strtoupper($word); // "STRING"


一方、アッパーキャメルケースっぽく先頭のみを英大文字にキャピタライズする場合は、先頭1文字と2文字目以降を分割して処理する必要がある。


●先頭のみを英大文字に
部分文字列を抜き出すならsubstr()関数の出番ということで
<?php

$word = 'string';

$Result = strtoupper(substr($word, 0, 1))
        . strtolower(substr($word, 1)); // "String"




●別のやり方で先頭のみを英大文字に(その1)
PHPでは特別にスカラーを配列的に参照することで部分文字にアクセスできるのでこれを使えば
<?php

$word = 'string';

$Result = strtoupper($word[0])
        . strtolower(substr($word, 1)); // "String"

※ $word[0]を$word{0}としても同様


●別のやり方で先頭のみを英大文字に(その2)
PHPでは頭文字だけを大文字変換する専用のucfirst()関数が用意されているのでこれを使うともっとコンパクトに書ける。
<?php

$word = 'string';

$Result = ucfirst(strtolower($word)); // "String"

ucfirst()関数は頭文字は変換するものの、以降の文字は元のままなので一旦strtolower()で全体を英小文字にする必要がある。


●番外
strtoupper()やucfirst()関数が内部でどんなことやってるかというと、ターゲットの文字コードが英小文字の範囲だったら小文字コードと大文字コードの差分をターゲットの文字コードから差し引いた数値を文字に直すといった感じでしょうか。

英小文字[a-z]は文字コード{0x61-0x7A}
英大文字[A-Z]は文字コード{0x41-0x5A}
の範囲に割り当てられているので

(a文字コード - A文字コード)で差分を出しても
(z文字コード - Z文字コード)としても同様の数値となる。
<?php

$word = 'string';

//差分は
$n = 0x61 - 0x41;

//この差分を条件を満たすターゲットの文字コードから差し引くので
if (0x61 <= ord($word[0])
    && ord($word[0]) >= 0x7A
) {
    $word[0] = chr(ord($word[0]) - $n);
}


部屋がトロピカルなので、アメちゃんやグミちゃんが溶け出してしまって包みから取り出しにくくなる。


冷蔵庫に入れるべきなのだろうか?


チョコレートなら冷蔵庫に入れるようにしていたけど、アメちゃんは迷うなぁ。。



アメちゃんの凝固点って意外と低いのねん。
もっと高くできないものかにぃ



PHPでは __(アンダースコア2つ)で始まる名前の関数(またはメソッド)は特殊な働きをするものが割り当てられている。(マジックメソッド)
代表的なものは __construct()、__destruct()など
これらを使いこなせたらいよいよPHP初級脱出といった感じかな?


■__autoload()という関数

未定義のクラスをインスタンス化しようとする(new演算子を使う)と、エラーを出す前の最終猶予段階として呼ばれる__autoload()関数(当然定義されてなければ呼ばれない)があります。

なので__autoload()関数を定義しておき、その内部で所定のクラス置き場からクラス定義が書かれたファイルを呼び出すように小細工ができる。
うまくいけば無事クラス定義を読み込むことができエラーを回避できる。

<?php

function __autoload($className) {

   require_once '/path/to/class/' . $className . '.php';
}

$obj = new foo(); // __autoload("foo")としてコールされる

なので「クラス名」と「クラス定義が書かれたファイル名」は一致させておくのが定石ということになる。

include_pathが通っていれば "/path/to/class/" が無くとも呼んでくれるだろうが、ソースコードを見て置き場所が明確に伝わってこないのは私の流儀に反するのでそれはやめておくことにしよう。。
なので実践で使う時は以下のようにシンプルでいいのさ

<?php

define("DIR_CLASS", "/path/to/class/"); // クラス置き場


function __autoload($className) {

   require_once DIR_CLASS . $className . '.php';
}

$obj = new foo(); // __autoload("foo")としてコールされる

クラス定義が読み出せなかったら即エラーになるので、file_exists()で事前のファイル存在チェックはもはや必要ないでしょ
でもそれよりもなによりもこんなもの使わないで事前にクラスぐらい呼んどけって話ではあるが。。
一体どう書くのがエレガントなんだろうか?


■__set()と__get()、ときどき__toString()

オブジェクトが持たないプロパティ(メンバ変数)にアクセスしようとすると呼ばれるメソッドがあります。
値を代入しようとすると呼ばれるのが__set()で、値を参照しようとすると呼ばれるのが__get()です。

<?php

class foo
{

}

$obj = new foo();
$obj->bar = 'test'; // 未定義プロパティにセット
echo $obj->bar; // セットした値を参照

上記のように、クラスに定義していないはずのプロパティに値セットして使うことはできます。
値セットする前にいきなり参照しようとすると当然未定義なので警告レベル設定によっては警告表示されることになります。

そこで__get()メソッドを定義しておくことで回避できそうです。
と同時に、アクセスするタイミングで小細工とかもできそうです。

<?php

class foo
{
   public function __set($name, $value) {

      $this->$name = '[' . $value . ']';
   }
   public function __get($name) {

      return '[]';
   }
}

$obj = new foo();
$obj->bar = 'test'; // 未定義プロパティにセット
echo $obj->fuga; // 未定義プロパティを参照
echo $obj->bar; // セットした値を参照

上記はどんなプロパティにアクセスしても必ず [ ] で囲まれるよう小細工したものです。

更にオブジェクト内部で値保持用のプロパティを用意すれば、もっといろいろ小細工できそうです。

<?php

class foo
{
   private $_data = array(); // 値保持用プロパティ

   public function __set($name, $value) {

      $this->_data[$name] = $value;
   }
   public function __get($name) {

      if (!isset($this->_data[$name])) $this->__set($name, '');
      return $this->_data[$name];
   }
   public function printProperty() {
      foreach ($this->_data as $key => $val) {
         echo "($key: $val)\n";
      }
   }
}

$obj = new foo();
$obj->bar = 'test'; // 未定義プロパティにセット
echo $obj->fuga; // 未定義プロパティを参照
echo $obj->bar; // セットした値を参照
$obj->printProperty(); // 扱ったプロパティを表示

これでオブジェクト外部からどんなプロパティ名にアクセスしても、まるで事前に用意されていたかのような感じになると同時に値の再利用を柔軟にできることになる。
上記はわざわざprintProperty()メソッドを用意したが、マジックメソッド__toString()で代用することもできる。

public function __toString() {
   $cat = '';
   foreach ($this->_data as $key => $val) {
      $cat .= "($key: $val)\n";
   }
   return $cat;
}

echo $obj; // オブジェクトを表示させてみる

__toString()メソッドから文字列を返すよう定義しておけば、オブジェクトを表示させようとするタイミングでこれが呼ばれることになる。


■__call()と__callStatic()

未定義のメソッド(メンバ関数)をコールすると、エラーを出す前の最終猶予段階として呼ばれるメソッドがあります。
作成済みのオブジェクトから呼ぶと__call()をコールしようと試み、静的に呼び出すと__callStatic()をコールしようと試みます。

なのでクラス内部に以下のように__call()や__callStatic()メソッドを定義しておけば、無いはずのメソッドが定義されていたことと同等になりエラーを回避できます。

<?php

class foo
{
   public function __call($name, $params) {
      echo "foo::__call()";
   }
   public static function __callStatic($name, $params) {
      echo "foo::__callStatic()";
   }
}

$obj = new foo();
$obj->bar(10); // __call('bar', array(10))としてコールされる

foo::fuga(1, 'a'); // __callStatic('fuga', array(1, 'a'))としてコールされる

これを使えば、よくあるセッターやゲッターの定義を自動化することなど便利に使えそうですね。


以上のようなマジックメソッドやリフレクション系のものなどは、どんな使われ方をするか事前にわからないことに対処するスマートな解決法だったりするのでココ一番という時に効果的に使っていきたい。
事実フレームワーク内部では多用されている。
要は使う人の為を思って、使いやすくしておくための裏工作に使う関数と言ったところでしょうか。

使う人は内部でどう処理されているかまでは分からなくとも、なんか便利に使えてしまう。

これが狙い。
これが目標。

そして・・・ 思いやり。