Php/php技術メモ
目次
- 1 dbクラス移行
- 2 参照渡し
- 3 参照渡し2
- 4 phpスクリプトをウェブサーバを使わずに実行する方法
- 5 クラスからクラスを呼び出す
- 6 変数値をクラス名とする
- 7 メソッド呼び出し
- 8 文字列分割について
- 9 配列の一部を削除
- 10 配列に追加
- 11 ソート逆
- 12 コード省略のメモ
- 13 エラーが表示されなくなる
- 14 スカラー値かどうか調査
- 15 変数値調査
- 16 配列格納確認
- 17 \n削除
- 18 半角カナを全角へ
- 19 エンコード変更
- 20 文字の数だけ連結させる
- 21 define使用方法
- 22 日付
- 23 日付再フォーマット
- 24 smartyコレできる?
- 25 タイムアウト時間を指定する方法
- 26 定義済み変数
- 27 2重forループを抜ける
- 28 printfの使い方
- 29 サニタイズ
- 30 self,parentについて
- 31 json
- 32 301リダイレクト
- 33 カスタムヘッダー
- 34 sessionが4日で切れる問題
- 35 PHP4,5共通で動く参照クラスの書き方
- 36 foreachの参照渡し(php5はOK、php4では使えない)
- 37 elseif規約
- 38 if一行判定
- 39 windows・linux互換パス区切りdefine
- 40 include_pathにパスを追加する方法
- 41 レスポンスデータ
- 42 機種依存文字の文字コード変換
- 43 php5でエラーメッセージがでない処理落ちの原因
- 44 エラーログファイルに文字列出力
- 45 携帯でsessionを使う方法
- 46 オブジェクト作成
- 47 printのバッファを取る
- 48 クラスをハンドラに設定するときの書き方
- 49 リバースプロキシ設定
- 50 do~whileの高度な使い方
- 51 処理後に独自関数を実行させたい場合
- 52 phpバッチでサーバのIP取得(linuxのみ
- 53 ipアドレス最後の数字を取得
- 54 url解析
- 55 パラメータの型指定
- 56 正規表現でmatchする日本語文字列を取得
- 57 iphone4バイト絵文字削除
- 58 長過ぎるwwwを3つに省略
- 59 プロセスユーザー表示
- 60 バッチでip取得
- 61 無名関数変数引き継ぎ
- 62 null判定でtrueのときnullを入れる
- 63 usersデータ配列からAgeのデータを配列に
- 64 dbの配列から特定のレコードを取得
- 65 array_filterで、関数化して引数を使う方法
- 66 dbの配列から単一カラムリストを取得
- 67 配列のキーをスネークケースからキャメルケースに変換する方法
dbクラス移行
Pear::DB → Pear::MDB2 速いらしい。
参照渡し
$a = "c"; $b = "a"; print $a; $a = &$b; $b = "b"; print $a;
参照渡し2
$a = 1;
test($a);
function test(&$aa) {
$aa += 1;
}
$aは2になります。
phpスクリプトをウェブサーバを使わずに実行する方法
windows d:\php5\php.exe d:\home\test\test.php
linux /usr/local/bin/php /home/user1/batch/test.php
perlの場合は
windows perl d:\home\test\test.cgi
linux perl /home/user1/batch/test.cgi
クラスからクラスを呼び出す
$objdb = new class_db;
$objdb->_main("a");
print nl2br(print_r($objdb,1));
class class_db {
var $main;
var $cla2;
function _main($s) {
$this->cla2 = new class_db2;
$this->cla2->_trim("c");
}
}
class class_db2 {
var $main;
function _trim($s) {
$this->main = trim($s);
}
}
変数値をクラス名とする
class test
{
var $param = 1;
}
class test2
{
var $param = 2;
function test2($add) {
$this->param = $this->param + $add;
}
}
$name = "test";
$test =& new $name;
print $test->param;
$name = "test2";
$test =& new $name(2);
print $test->param;
メソッド呼び出し
このように動的にメソッドを呼ぶことも可能
$this->m[$name] $this->$name()
文字列分割について
explode() は正規表現無し
splitはphpの正規表現で分割
preg_splitはperl互換の正規表現で分割
配列の一部を削除
unset($foo["bar"]);
配列に追加
$test[] = "test"; →とおなじ array_push($test, "test");
ソート逆
array_reverse($logs);
rsortは比較結果が等しくなる二つの要素があった場合、ソートした配列におけるそれらの並び順は不定となるようなので、↑を使ったほうが良い
rsort($logs);
コード省略のメモ
array_map("foo", $arr);
↓と同意コード
foreach ($arr as $value) {foo($value);}
エラーが表示されなくなる
error_reporting(0);
か
ini_set("display_errors",0);
//error_reporting(E_ERROR | E_WARNING | E_PARSE);
//ini_set("display_errors",1);
スカラー値かどうか調査
is_scalar($aaa);
変数値調査
$my=array("a","b","c","d","e");
var_dump($my);
//array(5) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> string(1) "c" [3]=> string(1) "d" [4]=> string(1) "e" }
print_r($my);
//Array ( [0] => a [1] => b [2] => c [3] => d [4] => e )
echo var_export($my);
配列格納確認
htmlで確認
echo nl2br(print_r($a),1);
コンソールで確認
echo nl2br(print_r($a),1);
コンソールで確認
echo var_export($a);
\n削除
$value = str_replace(["\r\n", "\r", "\n"], "", $value); // こちらの方が人気みたい。
or
$value= preg_replace("/(\r\n|\r|\n)/","",$value)
半角カナを全角へ
$value=mb_convert_kana($value,"KV");
エンコード変更
$value=mb_convert_encoding($value,"EUC-JP",mb_detect_encoding($value));
文字の数だけ連結させる
$value=str_repeat($str,$cnt);
define使用方法
define('TEST',"test1");
print TEST;
日付
print date('Y/m/d H:i:s',time());
日付再フォーマット
date("m/d H:i", strtotime('2010/10/3 10:10:10'));
smartyコレできる?
<{section name=num loop=$category}>
<option value="<{$category[num].id}>"><{$category[num].name}></option>
<{/section}>
バッククオートすればできる
タイムアウト時間を指定する方法
php.iniの以下を変える デフォルト30(秒)になっている
max_execution_time=30 ↓ max_execution_time=2000
~.phpに以下コードを加える
set_time_limit(2000);
定義済み変数
print __LINE__; // ライン print __FILE__; // ファイルの絶対パス print dirname(__FILE__); // ディレクトリ絶対パス
2重forループを抜ける
continue 2; // や break 2;
printfの使い方
sprintf('a=%d', $a);
サニタイズ
<?php
$a = array("a"=>1,"b"=>2);
$c = sanitize($a);
print nl2br(print_r($c,1));
/* 不正データ削除 */
function sanitize($data)
{
if (is_array($data)) {
return array_map('sanitize', $data);
}
return str_replace("\0", , $data);
}
self,parentについて
self、parentを使用してクラス内のプロパティ/メソッドにアクセスした場合、static宣言していない場合、エラーとなってアクセスできません。
json
ver5.2以降であれば標準で使える
$values = array('id' => '1', 'data' => 'test');
$json = json_encode($values);
// string '{"id":"1","data":"test"}'
$values = json_decode($json);
// $values = json_decode($str, true); 第2引数をtrueにするとオブジェクトでなく連想配列が戻る
print nl2br(print_r($values,1));
301リダイレクト
header("HTTP/1.1 301 Moved Permanently");
header("Location: " . $url);
カスタムヘッダー
header("X-hoge : piyo");
受ける側はレスポンスヘッダーを受け取り処理する。
X-は2012から非推奨っぽいが・・・。
sessionが4日で切れる問題
ini_set('session.gc_maxlifetime', 360000 * 100); // セッション初回設定から期限までの秒
ini_set('session.cookie_lifetime', 360000 * 10); // セッション再設定から期限までの秒
// ↑session_start();より上に書く
PHP4,5共通で動く参照クラスの書き方
class Af
{
var $data;
function set($data)
{
$this->data = $data;
}
function get()
{
return $this->data;
}
}
class Backend
{
var $_af;
function Backend()
{
$this->_af =& new Af;
}
function &getAf()
{
return $this->_af;
}
}
$b =& new Backend; $af =& $b->getAf(); $af->set(100); $af2 = $b->getAf();
foreachの参照渡し(php5はOK、php4では使えない)
foreach ($arr as &$value )
{
$value = 1;
}
elseif規約
else ifではなくelseifが正しい
if一行判定
$userに、ageがなければ0を入れる。
$user['age'] ?? 0
windows・linux互換パス区切りdefine
PATH_SEPARATOR
include_pathにパスを追加する方法
ini_set('include_path', '/lib:' . ini_get('include_path'));
php4.3以降
set_include_path('.' . PATH_SEPARATOR . dirname(__FILE__) . '/../application/lib/' . PATH_SEPARATOR . get_include_path());
レスポンスデータ
<form action="a.php" method="post"> <input type="checkbox" name="arr[]" value="aaa"> <input type="submit" value="send"> </form> print $_POST[arr][0] // aaaとなる
機種依存文字の文字コード変換
mb_convert_encoding("あいうえおⅡ", "utf-8", "sjis-win");
php5でエラーメッセージがでない処理落ちの原因
ini_set("memory_limit", "64M"); でメモリ値を大きくすると直る
エラーログファイルに文字列出力
error_log("test");
携帯でsessionを使う方法
ini_set('session.use_cookies', 0); // セッションIDの管理にCookieを利用するかどうかの設定です。
ini_set('session.use_only_cookies', 0); // セッションIDの保存をCookieのみで行うかどうかの設定。
ini_set('session.use_trans_sid', 1); // URLに自動的にセッションIDを埋め込むかどうかの設定になります。
を実行し、Aタグにsession_idを付加させる。 リダイレクトを使っているところは強制的に付加→sprintf("%s=%s",session_name(), session_id())
オブジェクト作成
$std = new stdClass(); $std->test = 1;
printのバッファを取る
ob_start(); echo "Hello "; $out1 = ob_get_contents(); ob_end_clean();
クラスをハンドラに設定するときの書き方
$this->register_outputfilter(array($this, 'smarty_outputfilter_test'));
リバースプロキシ設定
$_SERVER['HTTP_HOST'] = isset($_SERVER['HTTP_X_FORWARDED_HOST']) ? $_SERVER['HTTP_X_FORWARDED_HOST'] : $_SERVER['HTTP_HOST']; $_SERVER['REMOTE_ADDR'] = isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']; $_SERVER['SERVER_NAME'] = isset($_SERVER['HTTP_X_FORWARDED_SERVER']) ? $_SERVER['HTTP_X_FORWARDED_SERVER'] : $_SERVER['SERVER_NAME'];
do~whileの高度な使い方
do {
// 日付入力形式が異なるとき
if (checkdate($month, $day, $year)) {
break;
}
// 処理
} while(0);
処理後に独自関数を実行させたい場合
register_shutdown_function("__shutdown");
function __shutdown(){
echo "ended";
}
phpバッチでサーバのIP取得(linuxのみ
rtrim(`/sbin/ifconfig | /bin/grep inet | /bin/grep -v inet6 | /bin/cut -d ":" -f 2 | /bin/cut -d " " -f 1 | head -n1`);
ipアドレス最後の数字を取得
substr($ip, strrpos($ip, '.') + 1, strlen($ip))
url解析
$url = "http://google.com/hoge/piyo?test=1&test2=2"; $parse = parse_url($url); [scheme] => http [host] => google.com [path] => /hoge/piyo [query] => test=1&test2=2
パラメータの型指定
class Hoge{}
class Piyo{}
test(new Hoge()); // OK
test(new Piyo()); // NG
function test(Hoge $data) {
}
正規表現でmatchする日本語文字列を取得
// 日本語charsetが正しく設定されている場合
if (preg_match("!<name>([\W]*町)</name>!", $xml, $matches)) {
}
// 日本語charsetが正しく設定されていない場合
if (preg_match("!<name>([\w]*町)</name>!u", $xml, $matches)) {
}
// detail.kanji =""で囲まれた日本語charsetの部分を取得
if (preg_match("/detail.kanji = \"([^\"]*)/", $dataline, $matches)) {
}
iphone4バイト絵文字削除
mysqlのutf8でinsert時のエラーが起こるので削除する用途などに
$text = '右にくちびる | 💋 | 左にくちびる';
$text = preg_replace('/[¥xF0-¥xF7][¥x80-¥xBF][¥x80-¥xBF][¥x80-¥xBF]/', , $text);
// ちなみにmysql(utf8)のinsertエラー
SQLSTATE[HY000]: General error: 1366 Incorrect string value: '\xF0\x9F\x92\x8B\xE3\x83...' for column 'name' at row 1'
長過ぎるwwwを3つに省略
$str = "ぐーぐるWWWwwwwwwWWWWWwwwwwwWWWWWWwwwWWW:やほー";
$str = preg_replace("/[wwW]{3,}/iu", "www", $str);
// ぐーぐるwww:やほー
プロセスユーザー表示
echo posix_getpwuid(posix_geteuid())['name'];
バッチでip取得
$ifconfig = rtrim(`/sbin/ifconfig | /bin/grep inet | /bin/grep -v inet6`);
if (preg_match('/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/', $ifconfig, $matches)) {
print $matches[0];
}
`ifconfig`だとipが取れない可能性があるので、`/sbin/ifconfig`とする
127.0.0.以外
$ifconfig = rtrim(`/sbin/ifconfig | /bin/grep inet | /bin/grep -v inet6`);
if (preg_match('/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/', $ifconfig, $matches)) {
if ($matches[0]) {
foreach ($matches as $ip) {
if (!preg_match("/^127./", $ip)) {
echo $ip."\n";
}
}
}
}
無名関数変数引き継ぎ
$message = 'hello';
$example = function () use ($message) {
var_dump($message);
};
$example();
参考:http://php.net/manual/ja/functions.anonymous.php
null判定でtrueのときnullを入れる
php7以上の場合
$hoge = isset($hoge) ? $hoge : null;
これが
$hoge = $hoge ?? null;
こうかける
usersデータ配列からAgeのデータを配列に
$ages = array_map(fn(User $user) => $user->Age, $users);
dbの配列から特定のレコードを取得
$usersにdbから取得したfetch_all的な配列が入ってる
$tmp_users = array_filter($users, function($user)
{
return $user['user_id'] === 'hogehoge';
});
$tmp_usersには、user_idが 'hogehoge'だった1レコードの情報が、配列で、1つだけ入ってる。
array_filterで、関数化して引数を使う方法
public function find_user_by_user_id($user_id) : array
{
$users = $this->find_all('users');
$result = array_filter($users, function($user) use ($user_id)
{
return $user['user_id'] === $user_id;
});
if (empty($result))
{
return [];
}
return reset($result);
}
指定を2つにする場合
public function find_user_by_user_id_and_age($user_id, $age) : array
{
$users = $this->find_all('users');
$result = array_filter($users, function($user) use ($user_id, $age)
{
return $user['user_id'] === $user_id && $user['age'] === $age;
});
if (empty($result))
{
return [];
}
return reset($result);
}
指定を2つにする場合の処理を1行にしたとき
public function find_user_by_user_id_and_age($user_id, $age): array
{
return reset(array_filter($this->find_all('users'), fn($user) => $user['user_id'] === $user_id && $user['age'] === $age)) ?: [];
}
dbの配列から単一カラムリストを取得
$records = array(
array(
'id' => 2135,
'first_name' => 'John',
'last_name' => 'Doe',
),
array(
'id' => 3245,
'first_name' => 'Sally',
'last_name' => 'Smith',
)
);
$first_names = array_column($records, 'first_name');
print_r($first_names);
出力
Array
(
[0] => John
[1] => Sally
)
参考:https://www.php.net/manual/ja/function.array-column.php
キーの番号をカラム値にする
array_column()の3番目の引数にカラム名を入れる
$records = array(
array(
'id' => 2135,
'first_name' => 'John',
'last_name' => 'Doe',
),
array(
'id' => 3245,
'first_name' => 'Sally',
'last_name' => 'Smith',
)
);
$first_names = array_column($records, null, 'id');
print_r($first_names);
出力
Array
(
[2135] => Array
(
[id] => 2135
[first_name] => John
[last_name] => Doe
)
[3245] => Array
(
[id] => 3245
[first_name] => Sally
[last_name] => Smith
)
)
上記をid順位したい場合
// IDの配列を取得 $ids = array_column($records, 'id'); // IDでソート (昇順) array_multisort($ids, SORT_ASC, $records); print_r($records);
配列のキーをスネークケースからキャメルケースに変換する方法
/**
* スネークケースをキャメルケースに変換
*/
function snakeToCamel($string)
{
return lcfirst(str_replace('_', '', ucwords($string, '_')));
}
/**
* 配列のキーをスネークケースからキャメルケースに変換
*/
function convertKeysSnakeToCamel(array $array): array
{
$result = [];
foreach ($array as $key => $value) {
// キーを変換
$newKey = snakeToCamel($key);
// 値が配列の場合は再帰的に処理
$result[$newKey] = is_array($value)
? convertKeysSnakeToCamel($value)
: $value;
}
return $result;
}
