PHP + mysql を久しぶりにやる前に見ておく

個人的メモ

# ダメぜったい

- xxx.php ファイルの末尾の `?>` の後に空行や空白を不用意に入れない。
- mysql のパスワード書いたファイルを git add しない。

## 他言語との違いなど

- 文末にセミコロンが必要
- 変数名の冒頭に `$` が必要
- 明示的な型変換を必要としない。
 * 強制的に型を決めたいときは `$x = (int)$a` など。
- 文字列のクオートは '' または ""。
 * 文字列の連結は `.`； たとえば `$a .= 'hoge' . 'huga';`
- 配列はすべて連想配列扱い。
 * `$a[1]` は `$a["1"]` と同じ。
- コメントアウトは `//`
- グローバル変数はローカルスコープ内では無効
 * スコープ内で参照するには `global $val;` が必要
- 外部ファイルの読み込みは `require('filename.php');`
 * `include` は読み込めない場合でもエラーにならない
- `else if`, `elseif` 両方あり。 
- 標準出力への出力は `echo`：例えば `echo $a, $b, $c, "\n";`
 * print は引数が一つ。`.` で連結すれば同じような結果になるが同じではない。
- `null` や `nil` ではなく大文字で `NULL`
- `next` ではなく `continue`
- `switch` 文は基本は C と同じ (`case` 必要、`default` あり)。
 * `switch` 文内の `continue` は `break` 相当
- `for` は C と同じ: `for ( $i = 0; $i < 100; $i++ ){}`
- `foreach` もあり
 *  `foreach ( $array as $val ){}` 
 *  `foreach ( $array as $key => $val ){}` で key も取り出せる
- `#define` の代わりは `declare`: `declare(MAX_NUM=1);`
- クラスのメンバの参照は `->` (`.` は使わない)
- ヒアドキュメントは `<<<END` など


## コマンドラインで動作確認

```
$ php -v
```

## httpd サーバで php が動くか確認。

```index.php
<?php phpinfo(); ?>
```

ブラウザで開いたときに、php の情報がずらずらと出たら成功。

## 基本のコード

```pw.php
<?php
    $pw = 'password';
    $user = 'user';
?>
```

```base.php
<?php
    $buf = "";
    $database = "mydb";
    $host = "localhost";
    require("pw.php");

    try {
        $pdo = new PDO('mysql:host=localhost;mydb=iot;charset=utf8',$user,$pw,array(PDO::ATTR_EMULATE_PREPARES => false));
        $query = "select * from mytable;";
        $res = $pdo->query( $query );

    } catch (PDOException $e) {
        exit('DB connection refused.'.$e->getMessage());
    }

    $buf = "";
    foreach( $res as $name ){
        $buf .= $name[1] . "," . $name[2] . "," . $name[3] . "," . $name[4] . "\n";
    }
    echo $buf;
?>
```

## ソースその2

GET や POST の識別、ヘッダの取得など。雰囲気のみなので雑い。

```hoge.php
$content_type = explode(';', trim(strtolower($_SERVER['CONTENT_TYPE'])));
$media_type = $content_type[0];

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
  $content = file_get_contents('php://input');
} else if(isset($_GET['name'])) {
    $name = urldecode($_GET['name']);
    error_log( "table:" . $name. "\n", 3, "./error.log");
}else{
    error_log( "GET: no name\n", 3, "./error.log");
    exit(-1);
}
```

上のコードの error.log は .php ファイルのあるディレクトリを指す。パーミションがなければ書きこめない。

## 他の言語にあんまりない構文や規則

### 制御構文をタグの間をまたがって使える

```hoge.html
<?php if ($x == 5): ?>
xは5です。
<?php eles ?>
xは5ではありません。
<?php endif; ?>
```

これは下記とほぼ等価。

```hoge.php
<?php 
    if ($x == 5){
        echo "xは5です。";
    }eles{
        echo "xは5ではありません。";
    }
?>
```

for, while, switch なども同じようなことはできる。

### 可変変数

$ を重ねて付けて、変数の値そのものを変数名として使える。

```hoge.php
<?php
$a = 'test';
$$a = 'hoge';
echo $a;       // test
echo $test;    // hoge
echo ${$a};    // hoge
$test = 'huga';
echo $$a;      // huga
$h = 'bar';
echo ${$a}[0]; // h
echo ${$a[0]}; // bar
?>
```

### 配列の添字

配列はすべて順序付きの連想配列として扱われる。添字を数字にすると、小数でも整数と見なされる。true は 1 扱い。false は 0 扱い。(javascriptぽい)

```hoge.php
<?php
$array = array(
    1    => "a",
    "1"  => "b",
    1.5  => "c",
    true => "d",
);
var_dump($array);
// array(1) {
//  [1]=>
//  string(1) "d"
//}
?>
```

### echo の短縮

変数の前の等号は echo を意味する。

```echo.php
<?php =$val; ?>
```

これは

```echo.php
<?php echo $val; ?>
```

これと等価。