カテゴリー別アーカイブ: php

phpのテンプレートsmartyとか

最近久しぶりにPHPでサイトを作った。
その時smartyというテンプレートエンジンを使ったら便利だったという話。

テンプレートエンジンというのは、デザインとプログラム部分を分けることができるもので、
デザイン部分は普通のHTMLみたいに作って、プログラム部分と同じような変数を使うことで変数の中身だけ、プログラムファイルからデザイン部分に持ってこれる。
以前、pythonでdjangoは使ったことがあるんだけど、今回phpでテンプレートを使ってみて改めて便利だなと思った。

本業でプログラムをしてるわけじゃないから、PHPとかpythonとかjavaとか独学でちょこちょこ触る程度。
なので、テンプレートは難しそうというイメージがあった。だけど実際に弄ってみると、グーグルで検索して使い方を調べて30分ほどでインストールから実際にサンプルサイトを作るまでできた。
これは便利すぎる。一回使うと後はほぼ必須になる。

最近ドリームウィーバーも使い出してあまりの便利さに嬉しくなったんだけど、こういう便利ツールが実は全然難しいものじゃなくて、簡単な物だと知ってるかどうかは大きな違いだなぁと思った。

データベースのデータを定期的に順番に利用する

例えば、MYSQLデータベースのデータを1番から順番に(順番にの部分が重要)、1日10個ずつ利用するためにはどうしたらいいか調べた。
実際に選んだのは、カウンターとCRONを使った方法。
まず、実行ファイルは、CRONで一日一回動かす。
これはやり方は簡単なので省略。
次に、データベースから順番にデータを取り出す方法。
順番に取り出すには、連続性を持たせるために、取り出したデータの順番をどこかに一旦保存しないといけない。
そのために外部にテキストファイルを作って置いて、そこでカウンターを動かしてやることで、データの順番の記憶に使える。
PHPの場合は、実行ファイルの中に、以下を入れておき、同じ場所にcount.txtという空白のテキストファイルを置いてあげる。

$file_pointer = @fopen(“count.txt”,”r+”);
if(flock($file_pointer, LOCK_EX)){
$count = fgets($file_pointer, 65);
if(!isset($count) or !is_numeric($count)){
$count = 0;
}
$count++;
rewind($file_pointer);
fwrite($file_pointer, $count);
flock($file_pointer, LOCK_UN);
}else{
echo “失敗”;
}
fclose($file_pointer);

内容はテキストファイルを開いて、中の数字を取り出し、1を足して、新しく書き換えて保存するというもの。

このプログラムで、count.txtの中の数字が、プログラムがCRONで実行されるたびに1づつ増えていき、1,2,3,4,5,・・・となる。
この数字を利用すると、データを毎日順番に取り出して利用することができる。

$count++;

の部分を

$count–;

とすると、逆に一個ずつ減らすことも可能。
他にも方法があると思うけど、取り敢えず今はこの方法がお手軽なので使ってみた。

複数のテーブルの扱い

MYSQLのデータベースで、10万件くらいのデータが入ったテーブルが2つあって、
両方に共通したカラムがあって、
両方のデータを同時に使うために、内部結合とかビューを使ったら異様に遅くて、取り出すデータの量が多いと途中でとまってしまった。
たぶんやり方が悪いんだろうけど、試しに新しいテーブルを作ったらあっさり解決。体感的にはほぼタイムラグ足しで結果が取り出せる。
テーブルの作り方は簡単で

CREATE TABLE 新しいテーブル名 SELECT 選ぶカラム名 FROM テーブル1 JOIN テーブル2 ON テーブル1.共通のカラム名1=テーブル2.共通のカラム名2

CREATE TABLEの後は、内部結合のクエリをのそまま書いてあげるだけでできた。

できるだけシンプルなmysqlimportの使い方メモ

mysqlのデータベースにテキストやCSVファイルからデータをインポートする時、サイズが小さければphpmyadminでブラウザ上から簡単にクリックだけでインポートできる。
ただし、サイズが大きくて100Mのファイルなどは無理。ちなみに今回はロリポップ!と、さくらインターネットのレンタルサーバー上で試した。

そこで直接クエリを発行してインポートさせようとしたけど、はまった・・・。LOAD DATA INFILEとmysqlimportを使う2つの方法があるらしいんだけど、
最初にLOAD DATA INFILE 構文を使ってみたけど、無理だった。
次に、mysqlimportを使っていろいろ試してたら上手く行った。
データはtxtでもcsvでも成功。データ自体は前もってサーバー上にアップしておく。
以下phpでやる方法。

$frogs = ‘mysqlimport –host=ホスト –user=ユーザー –password=パスワード –fields-terminated-by=”,” -L データベース名 ファイル名’;
system($frogs);

これをサーバー上にアップして動かせばOK。
最初に、ネット上に転がっていた説明通りにしたんだけど、いくらやっても上手くいかなくて、いろいろ総当りで試して成功。
気をつける点は以下。
ホスト、ユーザー、パスワード、データベース名の箇所はお決まりのmysqlへ接続する時に使うものを入れる。
–fields-terminated-by=”,”の部分はフィールドの区切りに使ってある記号を指定。
-Lはローカルの意味で、このファイル自体をftpでサーバーにアップして使うので、この場合はそのサーバー上のファイルということになる(この辺自信なし)。
ファイル名はフルパスで指定。
/home/users/なんとかかんとか/test.txt
レンタルサーバーならこんな感じになる。
ここで指定したファイル名(拡張子は関係ない)と同じ名前のテーブル名を探してそこへデータがインポートされるので、あらかじめ、テーブルをちゃんとカラムの数やデータ構造など揃えて同じ名前で作って用意しておく必要がある。

300Mくらいのデータをインポートしてみたけど、数秒でインポートが終わった。かなり早い。

このへん、最初の一回は面倒だけど、一度できれば後はいろいろ使い回しができるので楽ちん。

mysqlは、必要な時に必要な物だけ調べて使ってるんだけど、一番最初に買った基礎からのMySQL 改訂版 (西沢 夢路)は良書で、今だに時々見返すことがある。自分でサイト作るためにmysql使っている人ならこれ一冊あれば十分な気がする。たぶん下手に小難しい本に手を出したら挫折してただろうなと思う。

preg_replaceによる置換で気をつけること

preg_replaceを使い、日本語の置換をするとき、マッチするパターンを持っているのに、スルーしてしまう箇所があるので調べてみた。
例えば、パターンにマッチする箇所を持つデータが100個あったとすると、20個ぐらいが置換できない。
完全に処理されないなら分かりやすいんだけど、半端な割合で処理がされないので、何が悪いのか迷ってしまった。

調べてみると、日本語とpreg_replaceの組み合わせだから起こる問題だとわかった。
パターン部分をUTF-8でエンコードして処理するとあっさり解決。
以下のように/の後にuを付けてあげる。

$x=preg_replace(‘/パターン/u’,’置換後’,$str);