mecab, mecab-phpをインストール

epelはyumのリポジトリ。
rpmコマンドは、RPMパッケージ(コンパイル済みのバイナリとファイル群)をインストールするもの。

[vagrant@localhost ~]$ mkdir mecab
[vagrant@localhost ~]$ cd mecab
[vagrant@localhost mecab]$ sudo yum install epel-release
[vagrant@localhost mecab]$ sudo rpm -ivh http://packages.groonga.org/centos/groonga-release-1.1.0-1.noarch.rpm
[vagrant@localhost mecab]$ sudo yum install mecab mecab-devel mecab-ipadic
[vagrant@localhost mecab]$ mecab --version
mecab of 0.996


[vagrant@localhost mecab]$ git clone https://github.com/rsky/php-mecab.git
[vagrant@localhost mecab]$ cd php-mecab/mecab
[vagrant@localhost mecab]$ sudo yum install libtool
[vagrant@localhost mecab]$ phpize
[vagrant@localhost mecab]$ make
[vagrant@localhost mecab]$ sudo make install
[vagrant@localhost mecab]$ sudo php -r "\$h=fopen('/etc/php.ini','a');fwrite(\$h,'extension=mecab.so'.\"\n\");"
[vagrant@localhost mecab]$ php -m | grep mecab
mecab

複数の配列の構造化マークアップ

例えば、コード、名称、取引値をそれぞれ配列に持っていて、jsonで吐き出したい場合。

<?php

$code = array("4579", "3758", "3825");
$name = array("ラクオリア創薬", "アエリア", "リミックスポイント");
$price = array("1728", "1805", "899");

?>
<script type="application/ld+json">
<?php

$items = array();
for($i=0; $i<3; $i++){
	array_push($items, &#91;
		"code" => "$code[$i]",
		"name" => "$name[$i]",
		"price" => "$price[$i]"
		]);
}
print(json_encode($items, JSON_UNESCAPED_UNICODE));
?>
</script>

テストデータは、Googleの構造化チェックツールで確認
https://search.google.com/structured-data/testing-tool?hl=ja

配列の構造化マークアップ

例えば、以下のように株価の配列を書き出す。

<?php

$array = array(
  "code" => "4779",
  "name" => "ラクオリア創薬",
  "price" => "1728"
);
?>
<script type="application/ld+json">
{
	"code" : "<?php echo $array&#91;code&#93;; ?>",
	"name" : "<?php echo $array&#91;name&#93;; ?>",
	"price" : "<?php echo $array&#91;price&#93;; ?>",
}
</script>

jsonにencodeすれば、吐き出す必要はなし。

<?php
$array = array(
  "code" => "4779",
  "name" => "ラクオリア創薬",
  "price" => "1728"
);
$json = json_encode($array, JSON_UNESCAPED_UNICODE);
?>

<script type="application/ld+json">
<?php print $json; ?>
</script>

配列の先頭を末尾に変える

PDOで、コード2929の銘柄が、株価416円、前日比+16%となり、それをデータベースに入れたいとする。
array(2929, 416, 18)を、以下のように、codeを末尾に変えるには?

$sql = "UPDATE stoph SET price = ?, ratio = ? WHERE code = ?";

array_sliceで切り取って、以下のように並び順を変える。

$today = array(2929, 416, 18);
$change = array_slice($today, 1);
$change[] = $today[0];

array(3) { [0]=> int(416) [1]=> int(18) [2]=> int(2929) }

$today = array(2929, 416, 18);
$change = array_slice($today, 1);
$change[] = $today[0];


$sql = "UPDATE stoph SET price = ?, ratio = ? WHERE code = ?";
$stmt = $dbh->prepare($sql);

$stmt->execute($change);

cronが動かないとき((getpwnam() failed)

cronが動かないのでコマンドラインで、cat /var/log/cron を打つと、

Feb 13 13:50:01 localhost crond[3093]: (/usr/bin/php) ERROR (getpwnam() failed)

getpwnamはパスワードファイルの取得にエラーがあるようです。

以下のように書き換えました。

// 前
00,10,20,30,40,50 * * * * /usr/bin/php /home/vagrant/api/test.php
// 後
00,10,20,30,40,50 * * * * root /usr/bin/php /home/vagrant/api/test.php

上手く動くようになりました。

### コマンドプロンプトの本
まあ買うまでもないかな

shuffle関数と配列の重みづけ

配列を重みづけしてシャッフルしたいと思います。

まず、単純な配列のシャッフル。

<?php

$arr = array('SBI証券','楽天証券','カブドットコム証券','松井証券','マネックス証券','岡三オンライン証券','GMOクリック証券','ライブスター証券');

shuffle($arr);
echo $arr&#91;0&#93;. "にしました。";

?>

岡三オンライン証券にしました。

重みづけの関数。

<?php


$arr = array(
	'SBI証券' => 30,
	'楽天証券' => 30,
	'カブドットコム証券' => 5,
	'松井証券' => 5,
	'マネックス証券' => 15,
	'岡三オンライン証券'=> 5,
	'GMOクリック証券' => 5,
	'ライブスター証券' => 5
);

function array_rand_weighted($entries){
	$sum = array_sum($entries);
	$rand = rand(1, $sum);

	foreach($entries as $key => $weight){
		if(($sum -= $weight) < $rand) return $key;
	}
}

$sec = array_rand_weighted($arr);
echo $sec. "にしました。";

?>

ああ、ダメだ。
やりたいのは、シャッフルした後の配列の順番の重みづけなので全然違いますね。これではどうでしょう?
係数とランダムな数を掛け合わせて、ソートします。

<?php

$min = 1;
$max = 10;

$arr = array(
	'SBI証券' => 30,
	'楽天証券' => 30,
	'カブドットコム証券' => 5,
	'松井証券' => 5,
	'マネックス証券' => 15,
	'岡三オンライン証券'=> 5,
	'GMOクリック証券' => 5,
	'ライブスター証券' => 5
);

foreach($arr as $key => $weight){
		$result[$key] = $weight * mt_rand($min, $max);
}
arsort($result);
var_dump($result);

?>

array(8) { [“楽天証券”]=> int(270) [“SBI証券”]=> int(120) [“マネックス証券”]=> int(60) [“ライブスター証券”]=> int(45) [“松井証券”]=> int(45) [“岡三オンライン証券”]=> int(30) [“GMOクリック証券”]=> int(20) [“カブドットコム証券”]=> int(15) }

値はさておき、近いのではないでしょうか。
$minと$maxの値を狭めることで、ボラティリティを低くできると思います。

条件分岐で先頭の文字を削除する

strstr最速といわれていますが、ここでは先頭の文字を判別すのに、preg_matchを使います。

<?php

$bank = '株式会社三井住友銀行';
if(preg_match("/銀行/", $bank)){
	echo $bank. "は銀行です。";
}

$word = array('株式会社三井住友銀行','ソニー銀行株式会社','シティバンク、エヌ・エイ東京支店');
foreach($word as $value){
	if(preg_match("/^株式会社/", $value)){
		echo $value. "は前株です。<br>";
	} elseif(preg_match("/株式会社$/", $value)) {
		echo $value. "は後ろ株です。<br>";
	} else {
		echo $value. "は株式会社ではありません。<br>";
	}
}

株式会社三井住友銀行は銀行です。
株式会社三井住友銀行は前株です。
ソニー銀行株式会社は後ろ株です。
シティバンク、エヌ・エイ東京支店は株式会社ではありません。

先頭文字を削除する

if(preg_match("/^hoge/", $text)){
     $text = ltrim($text, 'hoge');
  }

$_POSTでスクリプトの送信を制限する

$postをそのまま受け取ると、htmlタグやスクリプトを受け取ってしまいます。

例えば、以下のように、h1タグでhogeを囲って送ると、送られた先のhtmlでhogeがh1で表示されるケースを考えていましょう。

<h1>hoge</h1>

この場合、”htmlspecialchars” postから受け取った値を文字列に変換します。

$_SESSION["hoge"] = htmlspecialchars($_POST["foo"]);

結果、以下のように文字列として値が表示されます。

hoge

php foreach でpostが動かない訳

下記のように、ループしてnameが競合するとpostが動きません。

<?php 
  			foreach($result as $key => $value){
  				echo '<form method="post" name="form1" action="result.php">
			<a href="javascript:form1.submit()">' .$value.'</a>
    		<input type="hidden" name="search" value="' .$value.'">
			</form>';
  		}
  		?> 

nameをユニークにしたら、解消します。

<?php 
  			foreach($result as $key => $value){
  				echo '<form method="post" name="form'.$key.'" action="result.php">
			<a href="javascript:form'.$key.'.submit()">' .$value.'</a>
    		<input type="hidden" name="search" value="' .$value.'">
			</form>';
  		}
  		?> 

これを解決するのに、2時間くらいかかりました。私はいったい馬鹿??