PHP


WindowsにインストールしたxamppのphpをUTF-8化

WindowsにインストールしたxamppのphpをUTF-8化時のメモ。

2014年2月3日現在の最新版で行った。

1.「C:\xampp\php」にあるphp.iniを開く

下記の箇所を見つけて、コメントアウトをはずしていく。

----------------------------------------------
;mbstring.language = Japanese
;mbstring.internal_encoding = EUC-JP
;mbstring.http_input = auto
;mbstring.http_output = SJIS
;mbstring.encoding_translation = Off
;mbstring.detect_order = auto
;mbstring.substitute_character = none
;mbstring.func_overload = 0
----------------------------------------------

2.さらに、該当箇所は値を変更する

変更箇所と値
----------------------------------------------
mbstring.internal_encoding = UTF-8
mbstring.http_output = UTF-8
mbstring.encoding_translation = On
----------------------------------------------

XAMPPでFFFTPを使う

XAMPPでFFFTPを使うには、FTPユーザーの登録が必要。
ユーザー登録は、FTPサーバーであるFileZillaをXAMPPのコントロールパネルから起動して行う。

設定したIDとPASSを利用して、FFFTPを設定すればいい。

また、FileZillaで作ったユーザーには、書き込み・読み込み等の権限を同時に与えておくこと。
設定をしないとアップロードすらできない。

【PHP】連続した改行を一つにまとめる正規表現

連続した改行を一つにまとめる正規表現のサンプルコード
------------------------------------------
preg_replace('/(\n)+/us','$1',$contents);
------------------------------------------

もっと確実なの
------------------------------------------
preg_replace('/(\n|\r|\r\n)+/us',"\n",$contents);
------------------------------------------

"\n" の部分を ''(シングルクォーテーション)で囲むと \n の部分がそのまま表示され改行にならないので注意。

【PHP】対になるタグを見つけて間の文字列を取得する方法

htmlタグ間の文字列を取得するには正規表現を利用する

例:divタグ間の文字列を取得するサンプルコード
--------------------------------------------
preg_replace('/^.+<div>(.+?)<\/div>.+$/u','$1',$string)
--------------------------------------------

しかしこのやり方が通用するのは、限られた条件のときでしかない。
同じ要素のタグが入れ子になっている場合、不可能である。

divタグが入れ子になったHTML。これだとダメ
--------------------------------------------
<body>
<div>
テスト文章1
<div>
テスト文章2
<div>テスト文章3</div>
</div>
</div>
</body>
--------------------------------------------

何とか正規表現でできないものかと悩んだが難しそうなので、別の方法を用いた。

対になるタグというのは言い換えれば、二番目以降の開始タグと、そのひとつ前の閉じタグの位置を比較したとき、閉じタグが手前で、開始タグが奥にある状態の閉じタグである。

対のタグを見つけるサンプルコード
--------------------------------------------

//二番目の開始タグと最初の閉じタグの位置を確認する
$start_pos = mb_stripos($content_html,"<div",6); //二番目の開始タグを見つけたいので適当に6文字目から検索
$end_pos = mb_stripos($content_html,"</div>");

echo "<br>開始位置: " . $start_pos;
echo "<br>終了位置: " . $end_pos;

$i = 1;

//閉じタグが開始タグの前に来るまで繰り返し
while ($start_pos < $end_pos) {

$start_pos++; //次のタグを探すために1増加
$end_pos++;

//前回の位置以降のタグを探す
$start_pos = mb_stripos($content_html,"<div",$start_pos);
$end_pos = mb_stripos($content_html,"</div>",$end_pos);

//念のため10回繰り返してだめなら抜ける
if ($i > 10) {

echo "10回超えたので終える";
break;
}

$i++;

} //while

//対になるタグまでの文字列を抜き出す
$content_html = mb_substr($content_html,0,$end_pos);

--------------------------------------------

【PHP】simplexml_load_stringの使い方

シンプルにタグの間の文字を抜き出すサンプルコード
abcタグの間の文字を出力
----------------------------------------
<?php
//「$string = <<<XML」の下に改行は入れないこと!エラーになる
//行の先頭に半角スペースなどが入ることもないように(これコピペするとたぶん入る)
$string = <<<XML
<?xml version="1.0" ?>
<root>
<test>TEST1</test>
<test>TEST2</test>
<abc>xyz</abc>
</root>
XML;

$xml = simplexml_load_string($string);

//「->」(アロー演算子)で階層を下っていく
$content = $xml->abc;
print $content;
?>
----------------------------------------

testタグの間の文字を出力する
----------------------------------------
$content = $xml->test;
print $content;
----------------------------------------

但しこれだと最初のひとつしか出力されないので、すべて表示するには展開する。
----------------------------------------
foreach ($xml->test as $value) {
echo $value . "<br>";
}
----------------------------------------

【mysql】数値文字参照をUTF-8の文字に変換する

mysql等データベースに入った数値文字参照の文字列をUTF-8に変換する場合、mysql単体では無理なのでPHPを併用する。

数値文字参照を普通の文字に変換するPHP
------------------------------------------------------
$moji = mb_convert_encoding($moji, 'UTF-8', 'HTML-ENTITIES');
------------------------------------------------------
データベースから文字を取り出して、PHPで変換してUPDATEすればいい。

しかし文字列全てに対してmb_convert_encodingを行うと、希望しない文字まで変換してうまくいかないケースが出た。そこで数値文字参照の値にのみ変換をかけることにした。

文字列中の数値文字参照の値にのみ変換をかけるPHPサンプルコード
-------------------------------------------------------

//数値文字参照「&#~;」のみを拾う
preg_match_all ('/&#(.+?);/us',$string,$match);

foreach ($match[0] AS $moji1) {

echo "変換する文字:" . $moji1;

//数値文字参照をUTF-8に変換
$moji2 = mb_convert_encoding($moji1, 'UTF-8', 'HTML-ENTITIES');

//数値文字参照とUTF-8を置き換える
$string = str_ireplace($moji1,$moji2,$string);

}
-------------------------------------------------------

エンコードされたURLが%2Fや%5Cが含むと404エラーになる場合の回避法

URL変更など、mod_rewrite でURLを渡す時、「%2F」や「%5C」が含まれると404エラーが返ってくる。Apacheのデフォルト設定である。

「%2F」は「/(スラッシュ)を、%5Cは「\(バックスラッシュ)」をエンコードしたもの。
これらの文字を含んだURLで404エラーなる場合は、AllowEncodedSlashesを設定することでURLの使用可否を変更する。

httpd.confに追加する(.htaccessでは不可)
---------------------------
AllowEncodedSlashes on
---------------------------
エンコードされた「/」や「\」を含むURLの使用が許可される。

レンタルサーバーなどでhttpd.confをいじれない場合は、「/」や「\」を二重にエンコードすることでとりあえず回避できる。

「/」を二重にエンコードする例
---------------------------
$url = urlencode($url); //一回目のエンコード
$url = str_ireplace("%2f","%252f",$url); //二回目。スラッシュだけエンコード値に置換。
---------------------------

PHPでURLがリンク切れか調べる【get_headers】

PHPでURLがリンク切れか調べるには、get_headers関数でHTTPヘッダを取得する。(PHP5で追加された)

リンク切れ(404エラー)を調べるサンプルコード
----------------------------------------------
$head = get_headers($url); // HTTP リクエストに対するヘッダを取得する

$kekka = $head[0]; //添字0がステータスコード

echo $kekka;
//404エラーの場合「HTTP/1.1 404 Not Found」と表示される
----------------------------------------------

404エラー時にファイル書き込む場合
----------------------------------------------
if(stristr($info[0],"404")) {

//ファイルに書き込む
$fp = fopen("404list.txt", "a"); //aは追記
fwrite($fp, "404エラーです");
fclose($fp);

}
----------------------------------------------

但し、URLに半角スペースが使われていると、リンクがあっても404エラーが返ってくる。これを回避するためには、rawurlencodeで半角スペースを「%20」に置き換える必要がある。
urlencodeを使うと半角スペースは「+」に置き換わるが、これだと404エラーは回避できなかった。

【正規表現】文字列の否定、ある文字列を含まない

「abc」という文字列で始まらない
---------------------
^(?!abc).+$
---------------------

「abc」という文字列を含まない
---------------------
^(?!.*abc).+$
---------------------

Aの直後から「abc」という文字列を含まない繰り返し
---------------------
A((?!abc).)*?
---------------------

直後に「ABC」も「XYZ」もこないY
---------------------
Y(?!(ABC|XYZ))
---------------------

↓↓もう少し詳しく理解する。↓↓

(?!」と「)」で文字列を囲む正規表現を否定的先読みという。

これを利用すると、囲まれた文字(パターン)がある文字の直後に存在しない位置にマッチする。普通、正規表現はマッチする文字列を見つけるが、(?!――)はその位置を見つけるだけである。「^」が行頭、「$」が行末の場所を示すのと同じように(?!――)も場所を示すだけ

次のパターンと比較すると理解しやすい。

行頭から続く文字を繰り返している
-----------------
^.*
-----------------

(Aの直後から)abcという文字列を含まない位置にある文字を繰り返している
-----------------
A((?!abc).)*
-----------------

くどいようだが赤字はあくまでも位置を示す。

php_mecabで複合名詞を取り出すサンプルコード

単純に名詞が連続したら一つにまとめて取り出しています

サンプルコード
-----------------------------------------------------------------------------
parseToNode($txt); $node; $node=$node->getNext()){
if($node->getStat() != 2 && $node->getStat() != 3 && mb_strpos($node->getFeature(), '名詞', NULL, 'utf-8')===0){
$word .= $node->getSurface();
} else if ($word != '') {
array_push($meisi, $word); //渡された変数をarrayの最後に加える
$word = '';
}
}

//最後が名詞で終わった場合用の追加処理。
if ($word != '') array_push($meisi, $word);
//名詞の重複削除
$meisi = array_unique($meisi);

print("

");
print_r($meisi);
print("

");
?>
-----------------------------------------------------------------------------

3 / 512345