2010年12月11日土曜日

SQLiteのCall to a member function on a non-objectに再び悩み。。

SQLiteで
Call to a member function on a non-object
のエラーが再び出て、困った。

初心者によくあるSQL文の記述間違いが主であると複数のサイトで言われていたので、
SQL文を見返すも原因が見つからず。

やっと見つかった原因は単に、SQLiteのファイルへの接続が古いファイルに向いていたことだった。
新しいファイルの方へと接続し直したらOKに、というオチだった。。


SQLiteエラーの詳細表示

SQLiteでCall to a member function on a non-objectなどのエラーが出て、SQL文のエラー内容を表示させたいとき


$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);

のように設定すればOK。

2010年11月3日水曜日

getdate関数で、曜日を配列で受け取り、日本語変換して表示するメモ。

getdate関数で、曜日を配列で受け取り、日本語変換して表示するメモ。

    $daysofweek=array('日','月','火','水','木','金','土');
    $d=getdate(strtotime("2010/11/1"));
    echo $daysofweek[$d["wday"]];

例:月

2010年10月13日水曜日

phpDesigner7で、カーソルを行末から次の行へすぐ移らせる設定

phpDesigner7というphpの統合開発環境ソフトが気に入ったのだが、行末でカーソルが次の行に折り返してくれないのが残念だった。

「でもきっとそのオプションがあるだろう」と思って、もう一度よく見てみて,試してみると、ありました!!

tools preferences editorのscroll past end of lineという項目のチェックを外したらOKに!!


かなり幸せになれました。
これで普通に使える!!

2010年10月8日金曜日

Call to a member function bindParam() on a non-object に悩まされて。

 Call to a member function bindParam() on a non-object
というエラーに悩まされました。
SQLiteで。

要するに、ちゃんと変数なりが代入されていない,sql文として正しくないちゅうことですね。

郵便番号から住所取得するために、

       $sql="select zip,addr1,addr2,addr3 from zip where zip like ':search' order by zip asc";
        $stmt=$conn->prepare($sql);
        $stmt->bindParam(":search",$search);
        $stmt->execute();

のようにしていました。

いろいろやってみて、
':search'のクオーテーションを外してやったらOKでした。

bindParamしたパラメーターは、クオーテーションで囲んじゃいけないんですね。

       $sql="select zip,addr1,addr2,addr3 from zip where zip like :search order by zip asc";
としたら無事OKに。


良かった。

郵便番号をSQLiteに格納

これまでMySQLで郵便番号データを格納し、Ajaxで読み込ませていたが、
サーバを移行して、DB数が制限されたので、SQLiteに移行することにした。

■郵便番号csvファイルを落としてきて、csvファイルのいらないフィールドををできるだけそぎ落とし、(面倒なので、エクセルで。) ■""を削除し(何も考えずテキストエディタで置換)
■utf-8にして保存。(エクセル読み込み前にやると文字化けしたので、エクセルにてフィールド削除後に)
■で、PupSQLiteというソフトを使って,先にDBおよびフィールドを作っておいてやり、簡単に無事インポートできた。
http://www5.plala.or.jp/Pup/download/help/pupsqlite/function/readcsv.html

zipコードにuniqueを振ってしまっていて,最初エラーが出たが。
郵便番号は,北海道などでけっこう同じものがあるのでユニークを振ってはいけませんね。

PupSQLite、ありがたい。
作者様に感謝しています。

PHP Warning: Module 'mbstring' already loaded in Unknown on line 0 が大量発生

エラーログが膨大になっていたので、確認すると、
PHP Warning:  Module 'mbstring' already loaded in Unknown on line 0
というエラーが大量に発生していた。

色々調べて、
extension = mbstring.so
をphp.iniでコメントアウトしたら大丈夫になった様子。


二度ロードしていた、ということなんですね。


2010年10月7日木曜日

キーコードとアルファベット/数字の対応配列生成

javascriptでキーコードからアルファベットおよび数字を取得したいと思い、
そのための配列を準備。以下のコードに落ち着き。

for($i=0;$i<10;$i++){
    $code=48+$i;
    print "'".$code."' : '".chr(48+$i)."' , ";
}
for($i=0;$i<26;$i++){
    $code=65+$i;
    print "'".$code."' : '".chr(97+$i)."' , ";
}
chr()という関数、便利。初めて使った。

参考ページ:
http://tenderfeel.xsrv.jp/php/829/

2010年9月30日木曜日

SQLite2系と3系

SQLiteは2系と3系でけっこうSQL文で使えるものが違うようですね。

3系ではalter tableが出来るようになったとか。
やっと知りました。

参考になったのはこちら。
http://seclan.dll.jp/dtdiary/2007/dt20070228.htm

2010年9月28日火曜日

undefined function mysql_set_charset()で悩んだ。

とあるWebアプリを、新しいサーバ環境で動かそうとしたら、画面が真っ白。

デフォルトがエラー非表示設定だったので、php.iniを編集できるから、error_logをとることに。

log_errors =On
error_log=/home/hoge/public_html/php.log(みたいな絶対パスで指定)

として、書き込み権限を加えて準備。(エラーログが取れるかちょっとドキドキしました(笑)嗚呼、初心者)

エラーログを見てみると、 ちゃんとログが取れている。嬉しい。

そこで、undefined function mysql_set_charset() と書いてあって、「おや?」となりました。
なんで定義されてないんだろう。と、こんなときはグーグル先生。

どうもPHPのバージョンによって使える環境と使えない環境があるのですね。
mysqliが導入されていれば良い様子。
http://nonn-et-twk.net/twk/why-set-names-in-php-is-bad

結局、自分の場合は、DBの文字コードが整合性があったようで、この関数部分を削除したらすんなり通りました。
エラーログってありがたいなあ、と改めて思ったものでした。

2010年9月26日日曜日

「127」という数字ととTinyintの関係

SQL文を発行して、本来はid値が245となるところが、
「127」という数値になっていて少々悩んだ。

127は245のほぼ半数だから、どこかで割り算をしてしまっているかとソースを見るも、そんな箇所はなし。

弱ってDBのテーブル構造を見たら、該当idのフィールド型が「tinyint」になっていた。。

tinyintだったから127という数値で止まってしまっていたんですね。
245の半数ではなくて。

たまたま245なんて数値だったから,余計な悩みを抱えました(笑)。

理由が分かって良かった!!
127はtinyintの最大値。学習しました。。。。

2010年9月20日月曜日

sql文を発行してもうんともすんとも言わないときは。。

insert文やupdate文を発行しても、うんともすんとも言わないときは、
指定したカラムが存在するかどうかを確認するのもいいかもしれません。

xampp等のローカル環境と、サーバ上の本番環境・実験環境などとの間で、
もしかしてローカルだけに新しいカラムをつくり、
リモートサーバ上に作り忘れていた、なんていうことを、自分は何度かやらかしました。

ローカルではうまくいくコードが、
リモートではinsert等されない場合、
エラーも出ず、謎です。

そんなときは、カラムがちゃんとローカルとリモートで同一か、
書かれたsql文と整合性があるか、
しっかり確認するのは無駄ではないかもしれません。

自戒を込めて、メモしました。

column追加はALTER TABLE

sqlでカラムを追加するには、
ALTER TABLE tbl1 ADD column ~

checkboxにて複数の配列を渡す[]

Warning : Invalid argument supplied for foreach() in
という警告が出たので、メモです。

foreachに対して、配列を渡していない、と怒られたようなので、考えてみると、
postでcheckboxから値を複数渡したつもりで、複数渡していないことに気づき。

name='hoge'としていたので、
name='hoge[]'
としてみたら、無事解決でした。

checkboxの値を複数得るためには、[]が重要なり。

備忘録です。

2010年9月17日金曜日

予約語、ほんとに要注意

Warning: mysql_num_rows() expects parameter 1 to be resource, boolean given in..

というエラーが出て、しばし悩みました。

いろいろやってみて、あるカラム名に「group」という名前を付けていたことが原因と判明。
また「予約語」命名、やっちゃいました。
(前回は、こちら。http://learnaboutphpmysql.blogspot.com/2010/09/blog-post.html

「group」とか、フィールド名にしたくなっちゃいますよね。
初心者には痛いところです。

以後、「予約語要注意!」を更に徹底せねば、とまた思った次第でした。。

追記:groupというテーブルも作っちゃっていたので、変更。
alter table group rename to groups
ではまたまたエラーが出たので、
alter table `group` rename to `groups`
としたらOKでした。

予約語対策(フィールド、テーブル命名)、肝に銘ずべし。。

2010年9月11日土曜日

SQLiteをエクセル形式エクスポート

https://www.eonet.ne.jp/~pup/software.html

SQLiteをエクセル形式でエクスポート使用と思い、
「SQLite入門」に載っていたツールを思い出し、インストール。

とても簡単にエクスポートできました。
感謝。

[PupSQLite]

https://www.eonet.ne.jp/~pup/software.html

 

2010年9月9日木曜日

SQLiteではダミーのautoincrement値は要らない様子

SQLiteで
AUTOINCREMENTのidカラムには、
0などのダミーの値は必要無い様子。

0を入れると,すでに0があった場合、データがinsertできなかった。

メモです。

予約語使用、という痛い学習…

ちょっとしたDBをSQLiteで作成してみたら、
やたらと
Call to a member function bindParam() on a non-object in
というエラーに見舞われ、原因が分かりませんでした。

いろいろやってみて、「from」という名前のカラムへの登録をなくすと通ることが判明。
はっと思って「予約語表」を見てみたら、当然ですが「from」がありました。

っていうか、普通のSQL文でばりばり使われる言葉をカラム名にしちゃいけませんね。。。

痛い学習でした。2時間は悩んだ。。。修行が足りません。

「今後は気をつけましょう」と自戒を込めてココに書き残します。

SQLite,bindParamメモ

SQLiteでのPDO、bindParamの書き方が、
に載っていて、とても簡単だったので、引用メモです。

<?php
$stmt $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
$stmt->bindParam(':name'$name);
$stmt->bindParam(':value'$value);

// 行を挿入します
$name 'one';
$value 1;
$stmt->execute();

// パラメータを変更し、別の行を挿入します
$name 'two';
$value 2;
$stmt->execute();
?>

2010年9月8日水曜日

UPDATE文のメモ

UPDATEのメモです。

UPDATE table_name SET columnA=:valueA where id=:id

といった感じ。

「SET」をお忘れ無きよう!自分。

2010年9月2日木曜日

SQLiteで書き込みが機能しない時は、まずpermissionを疑うのが吉

前にもやりましたが、またやりました。。orz

SQLiteは、DBサーバが要らない分、サーバに上げた時の書き込み権限に注意する必要がありますね。
それをまた忘れて、書き込み権限を付与せず、
「insert intoが機能しない!」
としばし困り果てていました。。。

で、諦めて休憩したらふと、「あ、書き込み権限の問題かも」と思いつき、
権限を付与したら、あっさりOKに。。

SQLiteで書き込みが機能しない時は、まずpermissionを疑うのが吉ですね。
コードに問題が無く、エラーも出ないのにDBが空、なんて時は特に。

 自分に言い聞かせるためにも、またここに書いておきます。
きっと同じことで引っかかる方もおられるかな、とも思いつつ。

2010年8月30日月曜日

SQLiteでは、カラムを削除するコマンドが無い様子。

SQLiteでカラムを削除しようと思って調べたら、alter table などではできないらしい。

http://www.sqlite.org/faq.html

どうしても無くしたければ、新しいテーブルを作って、そちらにトランザクションなりで必要な部分だけをエクスポートして下さいな、ということですね。
そうなんですね。

以下、本家FAQからの引用。

型指定がないので、移行はかなり簡単そうではありますね。。
(11) How do I add or delete columns from an existing table in SQLite.

    SQLite has limited ALTER TABLE support that you can use to add a column to the end of a table or to change the name of a table. If you want to make more complex changes in the structure of a table, you will have to recreate the table. You can save existing data to a temporary table, drop the old table, create the new table, then copy the data back in from the temporary table.

    For example, suppose you have a table named "t1" with columns names "a", "b", and "c" and that you want to delete column "c" from this table. The following steps illustrate how this could be done:

        BEGIN TRANSACTION;
        CREATE TEMPORARY TABLE t1_backup(a,b);
        INSERT INTO t1_backup SELECT a,b FROM t1;
        DROP TABLE t1;
        CREATE TABLE t1(a,b);
        INSERT INTO t1 SELECT a,b FROM t1_backup;
        DROP TABLE t1_backup;
        COMMIT;

2010年8月28日土曜日

insert文には()が必要なんですね。

sprintf("insert into tbl (columnA,columnB) values ('%s','%s')",$a,$b);
のように、insert文を発行するとき、
valuesの後に括弧()をつけていなかったら挿入されず、しばし悩みました。

で、括弧()をつけたらすぐ解決。
良かった。

auto incrementの値をリセット

ALTER TABLE <テーブル名> AUTO_INCREMENT = 5;
のようにすれば、
連番を5から始められる。

間違って挿入したレコードを消去し、改めて挿入し直すときに、大量のデータを流し込んだものを削除した後だと連番にものすごく開きができるので、ALTER TALBEでリセットできるのはありがたい。

MySQLで。

insert intoで挿入されなくて悩んだ(文字コードの問題だった)

insert intoをsql文で書いても、
英字は挿入されるが、日本語がされなかった。
ローカル環境ではOKなのに、本番環境ではダメ。

日本語が通らないので、文字コードの絡みかな、とひらめいてチェックしたら、
ファイルの保存文字コードがSJISになっていた。。
UTF8に直して保存し直したら、ぶじOKでした。

未だに文字コードの保存ミス、やっちゃうな。残念!

2010年8月24日火曜日

explodeはそのまま配列を作る。

今日は、「explodeはそのまま配列を生成してくれる」と学習しました。

例えば、
$test="hoge,huga,foo,baa";
$ary=array();
$ary=explode(",",$test);
print_r($ary);
のような場合、

$ary[]=explode(",",$test);
のようにせず、
$ary=explode(",",$test);
と書けばOKだった。

さもないと、
$ary[0]の中に二次元配列が生成されてしまう様子。

2010年8月5日木曜日

datetime型のsortで10時前の時間がうまくソートされず、悩みました。

MySQLでdatetime型のソートをするとき、
9:00
11:30
17:00
と並べたいのに、

11:30
17:00
9:00
と並んでしまい、困っていました。

原因は、
order byで
date_format(start_time,'%k:%i') as start_time
といったように、フィールド名と同名で、24時間表記の10時前の時間から最初の0(ゼロ)を抜いていたことで、
order by start_time
としていたことが原因でした。

09:00が
9:00
となっていたことで、1より9が後、と判断していたのですね。

初歩的なミスでした。

2010年7月29日木曜日

wordでルビ付き文をコピーすると面倒だったので、括弧付き文を削除するスクリプト作成

wordでルビ付き文ファイルが送られてきて、その文をコピーすると、括弧にルビがくくられてこれまで困ってきました。

そこで、正規表現を使って、かっことその中の文字列を削除する簡単なスクリプトを書きましたので、ついでにアップしておきます。

http://labo.web-do.com/php/rubi.php

コードは至ってシンプルです。
$result=preg_replace("/\(.*?\)/","",$text);
みたいに置換しました。

「.*?」という指定、とても便利で気に入っています。
greedyでない検索、置換ができて。

2010年7月25日日曜日

半角24時間表記の数字を、time型に直す方法メモ

MySQLで半角数字にて24時間表記の時間データを格納したテーブルから、
12:00:00型のtime型に変換したくて、試行錯誤しOKだったのでメモです。

UPDATE time_table SET time_field = hour24*10000;
といったように、10000をかけるとOKでした。。

10000をかけるのね。。。。。。
3600とかかけちゃだめなのね。。。

ついでに、仮にminuteという名のフィールドに「分」情報も格納している場合、

UPDATE time_table SET time_field = hour24*10000+minute*100;
という風にすると OKでした。

よかった。

where でis

MySQLでデータ削除する際の備忘録。

delete from hoge where rel_date is null;
といったように、
where something = nullでなく
where something is null
にする。

2010年7月21日水曜日

mb_convert_kanaで変換されなかった。。

mb_convert_kanaを使っても、全角を半角に変換できず,しばし悩みました。

第三引数に文字コードを指定してやると解決。

$zip=mb_convert_kana("0000001","n","utf-8");
みたいな。

変数名の衝突で、はまった。。

とある変数名が,気づかずにバッティングしていて、
その変数名をキーとしたセッション変数になぜか格納され、
とても悩んでいました。
(ローカルでは大丈夫だったのですが、サーバに上げるとだめでした。)

いったい何でだか分かりませんでしたが、
変数名はちゃんと一意にすべきだと再確認。

くわばらくわばら。

2010年7月12日月曜日

gmailからPHPでデータを取得したいのでメモ

http://blog.s3ura.net/2010/04/01/182
にやり方が載っていて、
さっそくやってみたら、blogフィード形式で表示されました。

xmlデータを色々な形で取得できるそうなので、
学習&実験あるのみかな。。

http://gmail.1o4.jp/feed.html
にも情報がありました。


http://homepage.mac.com/travellers/blog/C1152805016/E1566781815/index.html
ラベルごとのフィードも取得できるようですね。


http://googlesystem.blogspot.com/2008/03/feed-for-unread-gmail-messages.html
海外の記事。

http://d.hatena.ne.jp/shimooka/20061202/1165043676
class化してコードを公開しておられるサイト。素晴らしい。。

2010年7月11日日曜日

cookieについての学習メモ

cookieの実装をまだこれまでまともにしたことがありませんでしたので、準備のためのメモです。
最初、jQueryでの実装と思いましたが、XSS脆弱性を少なくするために、やはりPHPを通じての実装にしました。
セキュリティ上問題ないものは、jQueryで行い、セキュリティ上より大事なものは、phpのsetcookie()でいこうかな、と。

setcookie解説ページへのリンクメモです。
http://php.net/manual/ja/function.setcookie.php

2010年7月5日月曜日

SQLiteで書き込みできず困った。。(ディレクトリの書き込み権限付与で解決)

SQLiteで書き込みができずに困った。

原因を検索したら、
http://blog.zuzara.com/2008/02/15/248/

ファイルのあるディレクトリの書き込み権限が必要、ということを読み、
実行したら、あっさり解決。。

ファイルの書き込み権限は変更していたが、
ディレクトリの方は気づかなかった。

解決して良かったが、なんとも悩みました。

2010年7月2日金曜日

SQLiteで携帯対応

SQLiteは基本UTF-8なので、
携帯表示の文字化け対応にちょっと苦労しました。

php.ini
で以下のようにしたらいけました。

output_buffering = On
output_handler = mb_output_handler

default_charset = "Shift_JIS"
mbstring.language = Japanese
mbstring.internal_encoding = UTF-8
mbstring.http_input = auto
mbstring.http_output = SJIS
mbstring.detect_order =  SJIS,EUC-JP,JIS,UTF-8,ASCII
mbstring.substitute_character = "none"
mbstring.encoding_translation = On


phpファイルはすべてUTF-8で保存し、
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
のままでいけました。
要するに、全てをUTF-8に統一して、php.iniでブラウザへの出力をSJISにする、
ということでいけるんですね。

(SHOEISHA刊「PHP逆引きレシピ」に書いてあるとおりにやったらいけました。
この本は、本当にありがたい本です。めちゃくちゃお世話になってます。)

2010年6月28日月曜日

left joinでもいっぺんにselect

select *,count(*) as count,hoge,fuga
 from a left join b on hoge.id=fuga.id;
といったように、二つのテーブルをleft joinするときも、
selectを書くのは一度でいいと分かった。
初めは、
select * from a select hoge,fuga from bのように
2回「select」を書いて,エラーに少し悩んだ。

ああ、初心者!

恥ずかしながら、メモです。

2010年6月27日日曜日

SQLite(PDO)でトランザクション、初成功

sqliteのPDOで、トランザクションを使わずに複数のSQL文を実行したら,やたら遅いので、トランザクションを勉強し、うまくいったのでメモです。

$stmt=$conn->beginTransaction();
for($i=0;$i<12;$i++){
$stmt=$conn->prepare("insert into tests (test,test_jp)
values(:test,:test_jp)");
$stmt->bindParam(":test",$tests[$i]);
$stmt->bindParam(":test_jp",$tests_jp[$i]);
$stmt->execute();
}
$stmt=$conn->commit();

bindとか、ちょっと面倒だし、
まだ使いこなせていません。。。

また、書き方が分からず、
$stmt=$conn->execute();としていたら、エラーだったので、
$stmt->execute(); というようにしたらOKに。

一方、SQL文を登録するにはprepare()内で書くと良い様子。
そっちは、
$stmt=$conn->prepare("insert into 。。。");みたいに$conn->が必要のようですね。

 まだよく分からない。。

が、とりあえず動いてくれて良かった!

■追記:西沢直木氏の「SQLite入門 第2版」「PHP辞典 第2版」の両方を見て、やっと少し分かってきました。PDOに関する記述は少なめで,まだよく分かりませんが、汎用性を獲得できそうなので、是非習得したいところです。

2010年6月14日月曜日

Postgreの文字コード変換のためのメモ。

PostgreSQLの文字コードを変換する必要があるので、参考になりそうなページをメモ。


http://itpro.nikkeibp.co.jp/article/COLUMN/20060227/230849/


http://neta.ywcafe.net/001031.html


nkfというコマンドが使えるんだな。。

2010年6月7日月曜日

Cannot send session cache limiter - headers already sentがでる場合メモ

「Cannot send session cache limiter - headers already sent」
という記述が出た場合は、
ブラウザに何か出力してからsession_start()している、ということの様子。

ブラウザに何かを出力する前に、session_start()する必要あり。

■追記:session_start()は、二度宣言しても問題ない様子。ある判別式の前と後の両方でsession_start()しても問題なかった。
一つ問題解決して、良かった。。

2010年6月6日日曜日

正規表現でアルファベットを抜いた時のメモ。

正規表現で、「<h2>長野NAGANO</h2>」といった文字列から、後ろのアルファベットを抜く際のメモです。

$match=preg_replace('/<h2>(.*[^\w])\w+<\/h2>/','$1',$str);

\wがアルファベットを示す。
()内の文字列をキャプチャーし、$1でアクセスできる。


■追記:$txt=preg_replace("/<h2>(.*?)([A-Z]+)<\/h2>/","<h2>$1</h2>",$str);
でもいけるっぽい。

2010年5月28日金曜日

テーブル名にハイフンはご法度

MySQLでテーブル名にハイフンを使うのは避けるのが吉。
どうしても付けたい場合は、バッククオートで囲むといいらしいが、避ける方が後々のためかな。

と思って、前にアンダースコアで命名したテーブル名を、
良く確認しないでハイフンだったと思ってselectしたら、
エラーが出て、しばし悩んだ(笑)

よって、「ハイフンご法度」と自分に覚え聞かせるために、この記事を書いています。

2010年5月25日火曜日

「三項演算子」、とっつきにくいが、覚えると便利。

三項演算子が使えると、かなりコーディングがすっきりして便利ですね。
なかなか使いこなせなかったのですが、
一度覚えると楽でした。

例えば
$var=$check==1?"checked":"";
みたいな形で書いていきますが、
if($check==1){
$var="checked";
}else{
$var="";
}
と書くより早いですね。

ありがたや。。

2010年5月23日日曜日

tortoiseSVNでのコミットショートカット(Ctrl+Enter)

tortoiseSVNでのコミットする時は、
Ctrl+Enterで一発だった。

マウスを握るのが面倒だったので、ありがたい。

2010年5月22日土曜日

PHP内でのsql文。。

PHPファイル内で、

$sql="alter table test rename to test2";
mysql_query($sql);
などとすれば(DBへの接続文はここでは省略)、
簡単にデータベースが変更できてしまうのですね。

知識として分かっていましたが、
やってみて、あまりの速さとあっけなさに、驚きを覚えました。

便利でもあり、かなり恐ろしくもあり。

2010年5月19日水曜日

等号記号は、二つで「等しい」の意味でしたね。。

Fatal error: Can't use function return value in write context in
というエラーが出て怒られて、しばし悩んでいました。

一晩寝たら、理由が思いついたのですが、
「=」(等号記号)の使い方間違いが原因でした。

要するに、=をイコール(等しい)の意味で使ってしまっていたので、
if(strlen($text)=7){・・・}
みたいな書き方をしていたのでした。。。

「==」と、二つの等号記号が必要でしたね。
いまだに間違えます。
まあ、小学校の時代から、この記号は「左右が等しい」という使い方をしてきたので、
その癖で書いてしまいますね。

以後、気をつけるべし、自分。

正規表現で、テーブルタグを一掃。

tableタグを一掃したくて、正規表現を書いてみたら、
うまくいったようなのでメモです。

$text="<tr><td><img>";
$pattern="(<t(d|r|able).*?>|<\/t(d|r|able).*?>)";
$result=preg_replace("/$pattern/","",$text);
echo $result;

今、tableで組んだ古いスタイルのサイトをリニューアル中なので、これで一気に取り組めそうです。
正規表現って、すごいすね。

「.*?」という「貪欲でない」正規表現、かなり使えますね。
これがないと、他の部分まで食ってしまう。

以下、PHPマニュアルの参照箇所です。

http://jp.php.net/manual/ja/regexp.reference.repetition.php


(■追記:&nbsp;もたくさん仕込まれていることしばしばなので、ついでに
$pattern="(<t(d|r|able).*?>|<\/t(d|r|able).*?>|&nbsp;)";
としてみました。)

正規表現のエスケープに関してのメモ

PHPにおける正規表現のメタ文字の一覧がマニュアルにあったのでメモです。
http://jp.php.net/manual/ja/regexp.reference.meta.php


[](文字クラス)内にあるかないかで、エスケープする必要のある文字が変わるのは分かっていても、
あやふやだったので、このページが参考になりました。

要するに[]内では、
\と
^と(文字クラス内の最初で使われる場合のみ)
-と
]
の四つだけのようですね。(ほんとかな。。マニュアルにはそう書いてあると自分には読めました。正確にはマニュアルをご参照ください。)

文字クラス内では、その他の文字はエスケープする必要が無い、ということでしょうか。
それなら簡単でありがたいです。

2010年5月17日月曜日

正規表現で、メルアドだけ抜き出したメモ。

正規表現で、以下のように名前の後に<>(小なり、大なり記号)でくくられた形式のメールアドレスを抜き取りたいと思い、うまくいったのでメモです。

「.*?」という正規表現がポイントでした。
「.*」が任意の一文字の0回以上の繰り返しですが、
そのままだと一番最後の「<」のところまでいってしまうので、 「?」をその前に付けてやると、”貪欲でない”選択となって、各><で囲まれた部分部分を抜き出してくれました。 「.*?」、ありがたや。 (以下のアドレスはもちろんダミーです。アットマークも全角文字になっています。)

$text="太郎<a@example.com>, 花子<b@example.com>,";
$text.="次郎 <c@example.com>,良子 <d@example.com>";
$result=preg_replace("/>.*?</",",",$text);
echo $result;

2010年5月14日金曜日

郵便番号データのインポート

郵便番号のインポートをしようと思い、方法を探していたら、以下のサイトが参考になりました。
http://plaza.rakuten.co.jp/pgmemo/diary/200512110000/


LOAD DATA LOCAL INFILE '/path/KEN_ALL.CSV'
INTO TABLE `sample_zip`
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'

というようにクエリを発行する、というのですが、
ローカルのxampp上ではどこにCSVファイルを置き、パスはどのように書くのか、少し迷いました。

で、以下のようにパスを指定したらいけました。
「¥(Web上だとバックスラッシュに化けそうなので、ここでは全角で表記しています。)」にする必要はなく、普通のスラッシュ区切りでいけました。

LOAD DATA LOCAL INFILE 'C://xampp/mysql/KEN_ALL.CSV'
INTO TABLE `zip`
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"';

0.532秒で全件を登録できた、というので、MySQL恐るべし、と感動しました。
(あ、テーブル名もzipに替えてます。念のため。。)

■追記:
データが大きすぎて、全件インポートできていませんでした。。
やはりデータを絞る必要があるかな、と。

お勉強ですな。。

order byの位置に注意。

sql文で、order byの位置を、whereの前に書いてエラーとなり、はまりました。

order byはwhere句の後ろに書かねばなりませんね。
注意すべし、自分。

URLの正規表現による自動リンク処理

正規表現で、URLを探し、自動的にリンクさせる関数のメモ。
簡易的ですが。。

長すぎるURLは60字でトリムして表示。

function url($text){
 $regex="s?https?:\/\/[a-zA-Z0-9;\/?:@&=\+$,\-_\.!~*'\(\)%#]+";
 if(strlen($text)>60){
  $text2=mb_substr($text,0,60);
  $text2=sprintf("%s...",$text2);
 }else{
 $text2=$text;
 }
 echo preg_replace("/$regex/","<a href=\"\\0\"
      target=\"_blank\">$text2</a>",$text);
}

array_search()は配列が第二引数

array_search()は第二引数が配列。第一が、探すべきvalue。

返るのは、最初に見つかったindex番号。
なければFALSEを返すはずだが、0が返ることもあるので注意。
の様子。

2010年5月13日木曜日

複数単語のハイライト

複数単語をハイライトさせようと思い、試行錯誤して出来たので、メモです。

function highlight($content,$word){
  if(is_array($word)){
   $num=count($word);
   $lighted[0]=$content;
   for($j=0;$j<$num;$j++){
    $k=$j+1; //$kを$jの先に進めておく。
//一単語ずつハイライトしていったものを格納。
    $lighted[$k]=str_replace($word[$j],
      "<span class='highlight'>{$word[$j]}</span>",$lighted[$j]);
   }
   return $lighted[$num];
  }
  else{
   $lighted=str_replace($word,"<span class='highlight'>{$word}</span>"
     ,$content);
   return $lighted;
  }
 }

2010年5月9日日曜日

tortoiseSVNで競合に悩み。

tortoiseSVNで、黄色い三角のビックリマークが出て、コミットもできず、clean upも機能しなくてまいっていました。

結局、一度exportを実行してから「edit conflict」を選択し、競合を解消する必要がありました。

黄色い三角のビックリマークは「競合」の意味だったのですね。

以下のサイトが参考になりましたm(_ _)m

http://hide.xsv.info/tips/svnmanual/conflict/

radioボタンの文字部分もクリッカブルに

radioボタンの文字部分をクリックしても選択できるようにしたいと思い、ググって実装したのでメモ。

<input type="radio" id="id1" name="name1" value="1">
<label for="id1">radio1</LABEL>

といったように、inputタグにidを命名してやり、labelでforの対象に、先ほどのidを指定してやればOKに。

ちょっと親切。

参考になったサイト:http://fefnir.com/school/5-1.htm

2010年5月7日金曜日

正規表現でURL(リンクメモ)

正規表現でURLを判別し、リンクを自動的に適用したい、と思ったので、ググったリンクメモ。

http://www.din.or.jp/~ohzaki/perl.htm#httpURL

なんかまだよく分かりませんが、
最近、正規表現のポケットリファレンスを買ったし、本気でだんだん勉強するつもりでおります。はい。

使いこなせるとかなり素晴らしいでしょうね。

千里の道も、一歩から。。

file名の取得メモ

ファイル名を取得するために、
   echo $_SERVER['PHP_SELF'];
を使おうかと思ったが、ファイル名だけ習得すればいいので、
  $dir=dirname(__FILE__).DIRECTORY_SEPARATOR;
  $file=str_replace($dir,"",__FILE__);
  echo $file;
の方が良い感じだった。

関数化してシンプルに使いたいが、今のところ外部ファイルで独自関数化すると、その外部ファイル名が習得されてしまうので、うまくいっていない。

また、定数化したら便利だろうかと思ったが、定数は一度定義されるとそのまま、と知らず、再定義ができないなど面倒だったのでパスすることに。

PHP5.3からは、__DIR__というマジック定数が用意されたようだが、まだ環境が整備されていないことがありそうなので、これもパスすることに。

2010年4月30日金曜日

[] operator not supported というエラーが出た

[] operator not supported
というエラーが出た。

ググッたら、
http://d.hatena.ne.jp/webpg/20100126/p1
こちらで教えてくださっていた方法があり、
やってみたらOKに。

配列にプッシュしていっていたのですが、
まず最初にその配列の初期化が必要だったのですね。
$arg=array();といったように。

それまでは出現していなかったので、何をやってしまったのか、まだ原因不明。
勉強だな。。

2010年4月26日月曜日

phpでcssの色設定を動的に変更したいのでメモ

phpでcssを動的に変更したいので、リンクメモです。
http://www.phppro.jp/news/384

適当なphpファイルにてcssファイルをつくるには、
header("Content-type: text/css");
を加えてCSSファイルに化けさせて、

<link rel="stylesheet" type="text/css"
 media="screen" href="style.php">
みたいに読み込ませる、と。

あとは、style.phpみたいなファイルの中で、
動的にデータベースから読み込ませた変数からスタイル指定してやれば良さそうだな、と。

実装、2,3日かかるかな。。

2010年4月23日金曜日

insert文ではカラム名はクオーテーションでくくらないのが吉。

MySQLでinsertする時に、
insert先のカラム名をシングルクオーテーションで囲っていたら登録されずエラーになっていました。
   $sql="insert into category ('cat_id','cat_name','sort_order') values ('dummy','$cat_name','$sort_order')";

なかなか理由が分からなかったのですが、シングルクオーテーションを外すと無事OKに。

   $sql="insert into category (cat_id,cat_name,sort_order) values ('dummy','$cat_name','$sort_order')";

なんとなくくくらないと心許ない気もしましたが、
これからはくくらない、と覚えておきます。。

printfで、引数を複数使ったり並び変えたりする際に$のエスケープが必要だった。

phpマニュアルに、printfで%s,%dなどに代入する引数の順番を変えたり、何度も代入したりできる便利な用法が載っていますが、エラーが出てうまく使えませんでした。 

$format 'The %2$s contains %1$d monkeys';printf($format$num$location);

結局問題は、""ダブルクオーテーションを使っていたので、その中で$記号をエスケープしていなかったことでした。
%1\$s,%2\$dなどとしてやると、無事順番入れ替えや同じ引数を複数回使ったりできました。
よかった。 

 ■追記:%1\$d と書くべきを、%\$1dと言う風に$を数字の前に書いてエラーも出てました。
 書き順注意。 

2010年3月26日金曜日

issetの方が、<>""より良さそう。

if($index<>"")といった判定式を、ある本から学んで使っていましたが、
if(isset($index))にしないと処理がおかしいときがありました。

これからは、issetを使うことにしよう、というメモです。

whereでorはカラム名を毎回記述する必要あり(SQLメモ)

SQLのクエリ文で、where ~ or ~を使うとき、
where some like 'foo' or some like 'bar'
といったように、同じカラムから探す場合でも、orの前後に両方同じカラム名を記述する必要あり。

これを省略していて、ちょっと悩みました。

2010年2月24日水曜日

SVNはチェックマーク付きフォルダ内を更新する必要があるんですね。(Tortoise)

tortoiseSVNでどうもうまくファイルが更新されない、と思って調べてみたら、
緑のチェックマークが入ったフォルダ内のファイルを更新しなくてはならないようでした。。
http://hide.xsv.info/tips/svnmanual/


最初のファイル群があったフォルダの配下にそのSVN用フォルダがローカルでつくられたのですが、
そっちのファイルを編集、更新する必要があるのですね。


色々最初は戸惑いますね。SVN..

2010年2月23日火曜日

svn checkout

svnでリポジトリから最新コピーを引っ張ってくるのが、checkoutらしい。

自分でファイルを上げているだけだから必要なさそうに思うが、
やはり大事なことのようなので、まずはやってみた。。

ほんっと、初心者ぶりを露呈していてお恥ずかしいが、うまくいって嬉しかったっす。

以下のサイトが参考になりました。
http://www.caldron.jp/~nabetaro/svn/svnbook-1.5-final/html-chunk/svn.tour.cycle.html#svn.tour.cycle.update

svnで最初にファイルをアップするには、svn import

初めてまともに、開発途中のミニアプリをsvnに上げてみました。
(backlogという無料のsubversionを貸してくれるところのサービスを使用しています。)

svn importがファイルをアップする行為だと知りました。
色々調べて、やっとアップロード(?)できて、ほっとした(^^;

2010年2月10日水曜日

配列中の特定の値を格納するindexを習得したかった。(解決)

配列の中にある特定の値を取り出したくて、どうすればいいか悩みました。

array_keysを使うと良さそうだとわかりましたが、
それだけでもだめで、
最終的にforeachを使うと望んだ結果を得られました。

以下のようにすると、 「2 7」という二つの結果が返ります。
これで、ある配列の中の特定の値を持つindexを習得できるようになりました。
よかた。

$ary=array('a','i','u','e','o','o','a','u');
$ary2=array_keys($ary,"u");
foreach($ary2 as $value){
    print $value." ";
};

それにしても、配列って、奥が深いです。。
したがってというか、配列関連の関数っていっぱいありますね。。

また、foreachも、使用法の理解がまだ漠然としています。
foreach($array as $key => $value)
なんて、使ってきてはいますが、理解がいまだにあやふやなところがあります。。

「キーと値」という言葉をしっかりとすぐ感覚的にわかるぐらい理解しなくてはいけませんね。。

ヒアドキュメントでの最終行にタブを入れてエラー

parse error, unexpected T_STRING,・・・うんぬんが出て、
ダブルクオーテーション'"'が余計だ、というエラーなのにどこにも余計なものが見つからず、
悩んでました。


すると、ヒアドキュメントの最後の行を間違ってタブでインデントを入れてしまっていたのが原因でした。。。orz


簡単なことだったっすね。

2010年2月8日月曜日

配列と日記(カレンダー)の連動。

配列って、まだよく使いこなせていません。
が、とても便利だとはわかってきました。

PHPの参考書を見ると、「条件分岐」の説明があり、大体その次ぐらいに「配列」の説明がお決まりのようにあり、「配列って大事なんだろうな」と思っていました、
が、よく飲み込めませんでした。

最近やっと分かってきたことは、
「PHPなどでは、一連の複数データを扱うことが多い」
ということで、
「そのため、配列に系統だってデータを格納すると便利である」
ということでした。

これって、分かっている方には当たり前すぎるのでしょうが、
「配列」はやっぱりプログラムに親しんでいない人間には最初わかりにくい(と思われる)ですし、
とりあえず自分はまだこんなところにいます(^^;

::::::::::::::::::::::::::::::::::::::::::

さて、今日は複数の値をMySQLからselectし、それをwhileで配列に格納していきました。
これは確かに便利でした。

具体的には、日記システムを作っていて、
一か月のカレンダーtable上の記事のある日の日付に、
 該当日記ページへのハイパーリンクをはってジャンプできるようにさせる、ということが課題でした。

while($row=mysql_fetch_array($sql)){
$diary[]=$row['id'];
$date[]=$row['date'];
}
みたいな感じで格納してゆき、
それを
array_search()を使って、各々の日に記事があるかどうかを判別し、記事がある日は$diary配列のインデックスを返す、ということをさせて、該当記事へのリンクを実現できました。

ああ、嬉しい。。。

カレンダーと日記のシステムは長年の夢でした。
漠然と「あったらいいなああああ」と思っていたことが、
PHP+MySQLで実現できてきて、
とても幸せなワタクシメです。

date型から一桁の月と日の数値を習得するときのメモ。

MySQLでdate型のデータをPHPでselectさせるとき、
一桁の月や日の前に「0(ゼロ)」が加わってしまって、処理が面倒でした。

date_formatを使うといい、ということがマニュアルでわかったので喜びました。

月は%c,日は%eで、0抜きの一桁の数値が習得できました。
http://dev.mysql.com/doc/refman/4.1/ja/date-and-time-functions.html

が、なぜかうまくselectされずまた悩みました。

原因は、
date_format("tourokubi","%Y-%c-%e")みたいにしていたのですが、
カラム名をクオーテーションで囲っていたことでした。

クオーテーションなしで、
select date_format(tourokubi,"%Y-%c-%e") as tourokubi2 というかんじにすると、無事表示されました。

バグ取り道、遥かなり。。。

sprintfでSQL文を書くときに%をうまく扱う方法(解決)

PHPでsprintfを使ってsql文を書くとき、%sなどを使うと便利ですが、
sql文でもwhere likeを使うと、where foo like 'baa%'みたいに%を使うので、
$sql=sprintf("select * from something where foo like '%s%'",$str);
みたいにするとエラーが出て困りました。

MySQLマニュアルを見てもよくわからず、PHPマニュアルを見るとちゃんと対処法が書いてありました^^
http://jp.php.net/manual/ja/function.sprintf.php の例5に書いてあります。

%%と%を二つ重ねるとリテラルとしてエスケープできるとのこと。

'%%s%'みたいにしてみたら、無事行けました。
よかった!

2010年2月1日月曜日

GD imagecreatetruecolorの背景色透過問題(解決)

GDでimagecreatetruecolor()を使うと、背景色が黒に設定されてしまいます。
他の色にするには、imagefillを使うといいのでしょうが、
透過させたい場合は困ります。

(自分は困りました。)

そんなわけで、imagecreatefrompng()をつかって、
予め作った透過PNGを
    $img = imagecreatefrompng("trans.png");
みたいに読み込ませてベースとし、
その上で色々な画像を生成させる、という方式でうまくいきました。
よかった。

以下はGDで生成した透過背景のPNG例です。


■追記
GDでPNGなどを生成すると、該当PHPファイルを指定すれば、それがそのままPNG画像としてブラウザは認識する、ということを知りました。
すごく面白いですね。使えます。
(Thanks to Kinoさん )

■追記2
なんか画像が変でした(^^;
png8で背景PNGを保存したらだめでした。PNG32で保存したらいけました。
ちょっとα値のことがよくわかっていません。要研究なり。

dechex(10進数から16進数へ)


「色彩の値を256といった10進数値からFFといった16進数に変換したいなあ」と思っていたので、関数を知れべたら、
dechex()という関数を知りました。

(dexhexと最初書いて、エラーが出ました(^^;)

これを使うと、for文で0~255までループさせ、その数値を16進数に変換して、テーブルセルのバックグラウンドカラーにprintfなどで代入できて、左の図のようなことができました。

ありがたや。

色を使ったいろいろな表現を考えているので、
dechexはお世話になりそうです。

hexdec()が逆の関数で、これもそのうち使うかな。。





一応、ソースを置いておきます。
表示は右が切れてますが、コピーしたらちゃんとコピーできますね。


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>dechexの応用による、色彩テーブル</title>

<style type="text/css">
table{border-collapse:collapse;} 
td{width:60px;text-align:center;padding:0;}
</style>

</head>

<body>
<table>
<?php
//純色で、数値を上げていく。
for($i=0;$i<256;$i=$i+16){
        $R0=sprintf ("<td bgcolor='#0%s0000'>#0%s0000</td>",dechex($i),dechex($i));
        $G0=sprintf ("<td bgcolor='#000%s00'>#000%s00</td>",dechex($i),dechex($i));
        $B0=sprintf ("<td bgcolor='#00000%s'>#00000%s</td>",dechex($i),dechex($i));
        $R =sprintf ("<td bgcolor='#%s0000'>#%s0000</td>"    ,dechex($i),dechex($i));
        $G =sprintf ("<td bgcolor='#00%s00'>#00%s00</td>"    ,dechex($i),dechex($i));
        $B =sprintf ("<td bgcolor='#0000%s'>#0000%s</td>"    ,dechex($i),dechex($i));
    if($i<16){echo "<tr>".$R0.$G0.$B0."</tr>";}
    else{echo "<tr>".$R,$G,$B."</tr>";}
}
//混色で、二色目の数値を上げていく。
for($i=0;$i<256;$i=$i+16){
        $RG0=sprintf ("<td bgcolor='#ff0%s00'>#ff0%s00</td>",dechex($i),dechex($i));
        $GB0=sprintf ("<td bgcolor='#00ff0%s'>#00ff0%s</td>",dechex($i),dechex($i));
        $RB0=sprintf ("<td bgcolor='#0%s00ff'>#0%s00ff</td>",dechex($i),dechex($i));
        $RG =sprintf ("<td bgcolor='#ff%s00'>#ff%s00</td>",dechex($i),dechex($i));
        $GB =sprintf ("<td bgcolor='#00ff%s'>#00ff%s</td>",dechex($i),dechex($i));
        $RB =sprintf ("<td bgcolor='#%s00ff'>#%s00ff</td>",dechex($i),dechex($i));
    if($i<16){echo "<tr>".$RG0.$GB0.$RB0."</tr>";}
    else{echo "<tr>".$RG.$GB.$RB."</tr>";}
}
?>
</table>
</body>
</html>

http://labo.web-do.com/php/colors/dechex2.php
にファイルを置いておきました。

テーブルだから、文字列を選択できるのがなんか嬉しい。 。

2010年1月30日土曜日

やっと色相環、完成。

望みがやっと達成されました。
綺麗に色相環が実現できました。
imagefilledarcとimagefilledellipseの両方を使って実現。
ありがたや。。。

<?php
    $img = imagecreatetruecolor(400, 400);
    $bg=imagecolorallocate($img,0,0,0);
    $r2=150;
    $s=1;$v=1;

function toH($a){
    $result=round((round($a,3)*255));
    return $result;
}
for($h=0;$h<360;$h++){
    $y0=$r2*(sin(deg2rad($h)));
    $x0=$r2*(cos(deg2rad($h)));
    $y=$y0+200;
    $x=$x0+200;
    
$hi = ( $h / 60 ) % 6;
$f = ( $h / 60 ) - $hi;
$p = $v * ( 1 - $s );
$q = $v * ( 1 - $f * $s );
$t = $v * ( 1 - ( 1 - $f ) * $s );

if($hi == 0){$r = $v;$g = $t;$b = $p;}
elseif($hi == 1){$r = $q;$g = $v;$b = $p;}
elseif($hi == 2){$r = $p;$g = $v;$b = $t;}
elseif($hi == 3){$r = $p;$g = $q;$b = $v;}
elseif($hi == 4){$r = $t;$g = $p;$b = $v;}
elseif($hi == 5){$r = $v;$g = $p;$b = $q;}
//else{$r = $v;$g = $v;$b = $v;}
$col=imagecolorallocate($img,toH($r),toH($g),toH($b));    
$col0=imagecolorallocate($img,0,0,0);    
imagefilledarc($img,200,200,300,300,$h,$h+1,$col
    ,IMG_ARC_PIE);
imagefilledellipse($img,200,200,200,200,$col0);

}
    header("Content-Type: image/png");
    imagepng($img);

?>

■今後の課題としては、色相環はできたので、
明度を下げてだんだん中心に向かってフェードさせる、
といったことを実現したいな、と。

IMG_ARC_NOFILLというstyle指定があって、淵だけが描かれるので、
それをつかって、中心に向かってだんだん明度Vを下げていこうかな、と。

外に向かっても少しずつ下げていくと綺麗かな。。

imagefilledarc()にて、色相環。

imagefilledarc($img,200,200,300,300,$h,$h+1,$col,IMG_ARC_PIE);
ということで、弧をつくってやると、また綺麗になりました。

第2、第3引数は、円の中心x.y座標。
第4、第5引数は、幅と高さ。
第6、第7引数は、開始角と終了角。
第8は、色。
第9は、どのような法則で描画させるかのオプションでした。
該当PHPマニュアルページ)

色相環、完成!

とうとう色相環が出来ました!(^^)!
ずっとエラーが出ていて、悩みました。
$rという変数を半径にしていたのですが、
$rはredの値を格納する変数にもしていたので、
バッティングしていたのに気づけませんでした。。

ともあれ、とりあえず完成です。

でも、filledellipseで360個の円をHSVの値を変えて表現しているので、
赤い円が最後にオレンジを食ってます。

これを、弧で実現すればたぶん行けると思うんですが、とりあえず今日は終了。




<?php
    $img = imagecreatetruecolor(400, 400);
    $bg=imagecolorallocate($img,0,0,0);
    $r2=150;
    $s=1;$v=1;

function toH($a){
    $result=round((round($a,3)*255));
    return $result;
}
for($h=0;$h<360;$h++){
    $y0=$r2*(sin(deg2rad($h)));
    $x0=$r2*(cos(deg2rad($h)));
    $y=$y0+200;
    $x=$x0+200;
    
$hi = ( $h / 60 ) % 6;
$f = ( $h / 60 ) - $hi;
$p = $v * ( 1 - $s );
$q = $v * ( 1 - $f * $s );
$t = $v * ( 1 - ( 1 - $f ) * $s );

if($hi == 0){$r = $v;$g = $t;$b = $p;}
elseif($hi == 1){$r = $q;$g = $v;$b = $p;}
elseif($hi == 2){$r = $p;$g = $v;$b = $t;}
elseif($hi == 3){$r = $p;$g = $q;$b = $v;}
elseif($hi == 4){$r = $t;$g = $p;$b = $v;}
elseif($hi == 5){$r = $v;$g = $p;$b = $q;}
//else{$r = $v;$g = $v;$b = $v;}
$col=imagecolorallocate($img,toH($r),toH($g),toH($b));    
imagefilledellipse($img, $x, $y, 50, 50, $col);
}
    header("Content-Type: image/png");
    imagepng($img);

?>

2010年1月29日金曜日

HSVからRGBに変換した値の表示。

一応、H=0~359の色相におけるRGBの値を256階層でテーブル表示させるコードが出来ました。
ずらっと長いテーブルが生成されます(^^;。

これを次は、GDででも色付けしてPNG化です。
楽しみなり。

その後、sin(),cos()あたりで色相環の完成か。
楽しみっす。。。
<?php

echo "<table cellpadding='1' border='1'>";
echo "<tr><th>H</th><th>R</th><th>G</th><th>B</th></tr>";
for($h=0;$h<360;$h++){
$s=1;$v=1;
$hi = ( $h / 60 ) % 6;
$f = ( $h / 60 ) - $hi;
$p = $v * ( 1 - $s );
$q = $v * ( 1 - $f * $s );
$t = $v * ( 1 - ( 1 - $f ) * $s );

if($hi == 0){
$r = $v;$g = $t;$b = $p;
}
elseif($hi == 1){
$r = $q;$g = $v;$b = $p;
}
elseif($hi == 2){
$r = $p;$g = $v;$b = $t;
}
elseif($hi == 3){
$r = $p;$g = $q;$b = $v;
}
elseif($hi == 4){
$r = $t;$g = $p;$b = $v;
}
elseif($hi == 5){
$r = $v;$g = $p;$b = $q;
}
else{
$r = $v;$g = $v;$b = $v;
}
echo "<tr><th>".$h."</th><td>".toHex($r)
."</td><td>",toHex($g),"</td><td>"
.toHex($b)."</td></td>";
}
echo "</table>";
function toHex($a){
    $result=round((round($a,3)*255));
    return $result;
}
?>
参考にさせていただいたページ。
http://movingahead.seesaa.net/article/139081151.html
感謝。

■後日に書いた追記です。
各度と円の6区分とRGB値と、x、y座標などを一覧表示させたテーブルページへのリンクをはっておきます。
 http://labo.web-do.com/php/colors/hsv_show.php
ちょっとRGBの背景色がいけてないんですが、眺めていると色々勉強になります。。

HSV色空間についてのメモ

最近、色相環をPHPで実現したいと思って、時々「どうしたら実現できるかなあ。。360度の6つの領域の色の変化を、各6領域でRGBをそれぞれ条件に沿って変化させるか。」などと考えていました。

が、ふと「HSV色空間」のことを知り、どうもその方向で実現できそうだとわかりました。
何事にも、先達のあらまほしきことなり。
やはり先賢は賢いなあ、と。


http://ja.wikipedia.org/wiki/HSV%E8%89%B2%E7%A9%BA%E9%96%93
wikipediaの「HSV色空間」へのリンク。
http://movingahead.seesaa.net/article/139081151.html
PHPで実現されたようであるかたのページリンク。
http://ja.wikipedia.org/wiki/%E5%90%88%E5%90%8C%E5%BC%8F
360を60で割って、その剰余を求める、ということが6領域をスマートに割り出す鍵であることが分かり、「mod」について勉強した際のwikipediaリンク。

少し理解できてきたので(まだかなり怪しいですが。。)、
GDでも使って色相環を実現したいな、と。

なんか、ずっと色相環を実現したかったんですよね~
憧れのような(笑)

がんばろっと。

(色々やることあるのに、何をやってるんだか、という突っ込みを自分に入れつつ。。)

2010年1月22日金曜日

やっと円が描けました。。

PHP+GDを使って円を描こうと思い、やっと描けました。
まだ、味も素っ気もねえですが。。(^^;
サインとコサインを使っての演習、ということで。

これから進化してゆきます。時計の文字盤とか、色をとりどりにするとか。RGBをいろいろ使って。。。



<?php

header('Content-type: image/png');

$image=imagecreate(400,400);
imagecolorallocate($image,200,200,200);
$color=imagecolorallocate($image,0,0,0);
for($i=0;$i<361;$i++){
        imagesetpixel($image,(200+(100*round(cos(deg2rad($i)),3))),(200+(100*round(sin(deg2rad($i)),3))),$color);
}
imagepng($image);
imagedestroy($image);

sinとcosを表にしてみました。(数学学習のため。。)

sinとcosの関係を理解したくて、ちょっとコードを書いてみました。
高校時代、意味不明でしたが、コードを書いているとわかってきました。

僕が関わる子供たちと、sin,cosの話をして、「どうやったら、わかるようになるかなあ。。」と考えていたので、こういうのはいいかな、と。
echo "<table border='1' cellspacing='0'>";
echo "<thead bgcolor='orange'><tr><th>角度</th><td>cos</td><td>sin</td></tr></thead>";
for($i=0;$i<361;$i=$i+30){
    echo "<tr><th align='right'>{$i}</th><td>".round(cos(deg2rad($i)),3)."</td><td>".round(sin(deg2rad($i)),3)."</td></tr>";
}
echo "</table>";

で、表示結果はこんな感じです。(round関数で、小数点以下3桁まで表示)




数学を簡単なプログラミングを通して学ぶと、一番効果的なんじゃないかと思うこのごろです。。

そのために一番子供たちに簡単に触れられるプログラミング言語はなんでしょうね。。。PHPは手軽ですが、ローカルに環境を作るのが難しいですし。。
探してみませんと。。

ラジアン値のこと、やっと理解。。

ラジアン値ってなんだろう?と思い、
角度からラジアン値を算出する関数deg2rad()を使って調べて、やっと理解しました。

echo deg2rad(45)."<br />";
echo deg2rad(180)."<br />";
echo deg2rad(270)."<br />";
の値はそれぞれ、
0.785398163397
3.14159265359
4.71238898038
です。

要するに「180度」が円周率の値なんですね。
半径の長さに等しい弧に対する中心角の大きさを一ラジアン
という文を見つけましたが、そういうことなんですね。
なるほど。。

昔ならったような気もしますが、完全に失念していました。

でも、これを使えばプログラムを使って円周上に点を置いていくような座標の計算がとても楽になる、とわかって、俄然理解への意欲がわきました。

必要こそ、理解の母ですね。

M_PI(円周率の定数)、便利。

PHPで(他の言語でものようですが)、円周率がM_PIという定数で定義されていて、便利でした。

echo M_PI."<br />";
echo (M_PI/8)."<br />";
echo M_PI_4."<br />";
echo M_PI_2;
の結果は、
3.14159265359
0.392699081699
0.785398163397
1.57079632679
みたいな感じで。

ありがたや。。

2010年1月20日水曜日

正規表現でかっこ()に囲まれた部分を全部削除したかった(解決)

正規表現で、ある文章からかっこ()に囲まれた部分を全部なくしたい、と思い、色々試してやっと実現できたので、メモです。
とにかく何でもいい文字の連続を表現するには、「.*」(ピリオドアスタリスク)でいけるんですね。
preg_replace("/(\(|().*(\)|))/","変えたよ",$str)
要するに、かっこの半角と全角の両方を|で認識させるようにして、半角かっこはもちろんバックスラッシュでエスケープして、それを半角かっこでくくってグループ化し、そのあとに閉じかっこも開きかっこと同様にグループ化して指定して、その間に.*を入れてカッコ内にどんな文字があってもOKになった、と。


やや時間がかかりました。。解決して嬉しいです(笑)
参考になったページはここ。とてもよく分かりましたm(_ _)m「サルにもわかる正規表現入門」。
http://www.mnet.ne.jp/~nakama/

::::::::::::::::::::::::::::::::::::::::::

■追記:この方法に弱点を発見しました。。
いくつもの()に囲まれた部分が、同一文内にあると、一番最初の開きかっこから、一番最後の閉じかっこまでがくくられて、ひとつと認識されてしまい、途中の文章が全部ずっぱり消えてしまいます。。
.*は可能な限り最後までつなげられる、という法則があるからですね。。

さて、困りました。どうしようかな。。

■追記2:一応解決です。応急策。
preg_replace("/(\(|().{5,30}(\)|))/","OK",$str);
みたいに、間にある文字数をだいたい指定してやれば、まあまあいけそうです。ちょっとアナログちっく。

■追記3:指定した文字数がマルチバイトの文字数じゃないので、どうしよう、とおもったら、pregはuというutf-8オプションがあったので、uを追加してやると日本語を一文字として認識してくれたようです。ありがたや。。
preg_replace("/(\(|().{5,10}(\)|))/u","OK",$str);

2010年1月18日月曜日

pos()という関数名はすでにあった。。

自前の関数をつくってpos()と名付けたら、既に予約されてました。
こういうシンプルなのは避けないとだめですね。

遥かなる脱初心者の道。。

関数の引数にあてる変数名は同じの方がいい様子。

自前の関数を作ったらエラーが出るので悩みました。
 syntax error, unexpected '$'

function pretrim($pretrim,$keyword){
中略
}
みたいなのをつくって、

pretrim($answer,$word)として使おうとしていたのが駄目だったようです。

function pretrim($answer,$word){}として引数を同じ変数名にしてやるとOKでした。
よかった。

2010年1月16日土曜日

printf()とsprintf()の違いがわかりました。。

printf()とsprintf()の違いがよくわかりませんでした。が、やっとわかりました。

printf()は出力して、sprintf()は値を返す(変数に代入できる)、ということなんですね。
printf()の中に引数を入れて変数に代入してみたり、
sprintf()でecho()のように出力させようとしてみたりして、うまくいかず、
やっと意味が分かりました。。

mb_strposやmb_strlenで文字数がおかしかった(解決)

mb_strlen()などでマルチバイトの文字数がちゃんと計算されないので悩みました。
"utf-8"を引数で設定したらOKでしたが、面倒です。。

phpinfoで調べたら、php.iniで設定しているはずなのに、 mb関連がno-valueとか書いてありました。。

原因は、xamppの1.6.8を使っていて、php/php.iniを変更していたのがまずかったようで、apache/bin/php.iniの方を設定すれば直りました。。。

1.7.1からphpディレクトリ配下のphp.iniが生きるようになってるんですね。。。

2010年1月14日木曜日

session学習開始

sessionの学習を開始しました。

POSTとGETでは、あるページからあるページへのデータの受け渡しだけでしたが、
SESSIONを使うと、ブラウザを開いている間ずっと(設定すれば閉じたのちも)、データを保持して渡してゆける、というのはとても便利。

ありがたい仕組みです。。。

2010年1月7日木曜日

RGBテーブルその二

RGBのテーブルをまたつくりました。
サイトのバックグラウンドを作ろうとしています。

超コードがひよっこですが、ご照覧を。。。
(知り合いの方からsprintfを使えば、%xで16進数としてとれる、ということを教わりました。その方が断然簡単ですね!)



<html><head><style type="text/css"><!--table {font-size:0.8em;}-->
</style><body >
<?php
function deg2sixteen($deg){//10~15までをa~fに変換
    switch($deg){case 10:$deg="a";break;case 11:$deg="b";break;case 12:$deg="c";break;case 13:$deg="d";break;case 14:$deg="e";break;case 15:$deg="f";break;}//i switch end
    return $deg;}
echo "<table border='0' cellspacing='0' cellpadding='0'><tr>";//sell-paddingの値を0にする必要があった。
for($n=0;$n<4;$n++){//RGBそれぞれ2色ずつのテーブルをつくるループ
    echo"<td><table border='0' cellspacing='0' cellpadding='0'>";
        for($y=0;$y<16;$y++){//第一のカラーを0~15まで推移させる。
        echo"<tr>\n";
        if($n<2){$y2=15-$y;$yc=deg2sixteen($y2);}//この二行で上下を逆に。
        else{$yc=deg2sixteen($y);}
            for($x=0;$x<16;$x++){//第二のカラーを0~15まで推移させる。
                if($n%2==0){$xa=15-$x;$xc=deg2sixteen($xa);}//この二行で左右を逆に。
                else{$xc=deg2sixteen($x);}
                $y2=$yc."0";$x2=$xc."0";$z2="00";//ここで二ケタに変換
                switch($n){//ここでRGBから二色を選ぶ振り分け。
                    case 0:echo"<td bgcolor='#".$z2.$y2.$x2."'>#0".$yc.$xc."</td>\n";break;
                    case 1:echo"<td bgcolor='#".$x2.$y2.$z2."'>#0".$yc.$xc."</td>\n";break;
                    case 2:echo"<td bgcolor='#".$y2.$z2.$x2."'>#".$yc."0".$xc."</td>\n";break;
                    case 3:echo"<td bgcolor='#".$y2.$z2.$x2."'>#".$yc."0".$xc."</td>\n";break;
                }//$n switch end
            }//j for end
        echo"</tr>\n";
        }//i for end
    echo"</table></td>";
    if($n%2==1){echo"</tr><tr>";}
}//for n end
echo"</tr></table>";
echo "<table border='0' cellspacing='0' cellpadding='0'><tr>";//sell-paddingの値を0にする必要があった。
for($n=0;$n<4;$n++){//RGBそれぞれ2色ずつのテーブルをつくるループ
    echo"<td><table border='0' cellspacing='0' cellpadding='0'>";
        for($y=0;$y<16;$y++){//第一のカラーを0~15まで推移させる。
        echo"<tr>\n";
        if($n<2){$y2=15-$y;$yc=deg2sixteen($y2);}//この二行で上下を逆に。
        else{$yc=deg2sixteen($y);}
            for($x=0;$x<16;$x++){//第二のカラーを0~15まで推移させる。
                if($n%2==0){$xa=15-$x;$xc=deg2sixteen($xa);}//この二行で左右を逆に。
                else{$xc=deg2sixteen($x);}
                $y2=$yc."0";$x2=$xc."0";$z2="00";//ここで二ケタに変換
                switch($n){//ここでRGBから二色を選ぶ振り分け。
                    case 0:echo"<td bgcolor='#".$y2.$z2.$x2."'>#".$yc."0".$xc."</td>\n";break;
                    case 1:echo"<td bgcolor='#".$y2.$z2.$x2."'>#".$yc."0".$xc."</td>\n";break;
                    case 2:echo"<td bgcolor='#".$z2.$y2.$x2."'>#0".$yc.$xc."</td>\n";break;
                    case 3:echo"<td bgcolor='#".$z2.$y2.$x2."'>#0".$yc.$xc."</td>\n";break;
                }//$n switch end
            }//j for end
        echo"</tr>\n";
        }//i for end
    echo"</table></td>";
    if($n%2==1){echo"</tr><tr>";}
}//for n end
echo"</tr></table>";
?>
</body>
</html>

2010年1月6日水曜日

mb_convert_kana()で変換できなかった。("utf-8"が必要だった)

http://life1204.blogspot.com/2008/07/mbconvertkana.html

mb_convert_kana()で全角半角が変換できず悩んでいたら、上記のサイトを見つけ、無事解決。

第三引数に"utf-8"を入れてやればOKなんですね。
$str=mb_convert_kana($str,"an","utf-8");
みたいに。

全角文字、数字を、これで無事変換できるのはありがたい。。

2010年1月4日月曜日

RGBの色相をテーブル表示

RGBの色相階調を16進数表記させながらテーブルで表示させるプログラムを書いてみました。

最初、<td>のbgcolorの値に、”#F00”といった三桁の省略形で書いていたので、黒い背景になってしまい、しばし悩みました。6桁でちゃんと書かないといけないのですね。(ですので、画像にある3ケタ表示は簡略表示しているだけですのであしからず。)

なんか、簡単なプログラムでとても美しいものになったので、ちょっと嬉しくなって投稿してみました。
初心者なコードで笑われるかもしれませんが、一応コードもアップしておきます。

自己ログも兼ねまして。。

<?php

function deg2sixteen($deg){//10~15までをa~fに変換
    switch($deg){
        case 10:$deg="a";break;
        case 11:$deg="b";break;
        case 12:$deg="c";break;
        case 13:$deg="d";break;
        case 14:$deg="e";break;
        case 15:$deg="f";break;
    }//i switch end
    return $deg;
}
for($n=0;$n<3;$n++){//RGBそれぞれに色ずつのテーブルをつくるループ
switch($n){
    case 0:echo"赤Rと緑Gの混色図";break;
    case 1:echo"緑Gと青Bの混色図";break;
    case 2:echo"赤Rと青Bの混色図";break;
}

echo "<table border='0' cellspacing='0'>";
echo "<tr>";
for($i=0;$i<16;$i++){//第一のカラーを0~15まで推移させる。
    $ic=$i;
    $ic=deg2sixteen($ic);
    echo"<tr>";
    for($j=0;$j<16;$j++){//第二のカラーを0~15まで推移させる。
        $jc=$j;
        $jc=deg2sixteen($jc);
        $ic2=$ic.$ic;$jc2=$jc.$jc;$zero="00";//ここで二ケタに変換
switch($n){//ここでRGBから二色を選ぶ振り分け。
    case 0:echo"<td bgcolor='#".$ic2.$jc2.$zero."'>#".$ic.$jc."0</td>";break;
    case 1:echo"<td bgcolor='#".$zero.$ic2.$jc2."'>#0".$ic.$jc."</td>";break;
    case 2:echo"<td bgcolor='#".$ic2.$zero.$jc2."'>#".$ic."0".$jc."</td>";break;
    }//$n switch end
    }//j for end
    echo"</tr>";
}//i for end
echo"</table><br>";
}//for n end

?> 

■追記:deg2sixteen()という自前の関数を作って、
10~15までの数字をa~fまでの英字に返還させるようにしたのですが、
Fatal error: Can't redeclare already declared function
のエラーが最初出て困りました。
要するに関数を複数回宣言している、ということなので考えてみたら、
for文の中で宣言していました。。(^^;
for文の外で宣言してやると、無事いけました。

ああ、初心者(笑)

SIN,COSの使い道。(GDで円形に図形を配置)

GDを使って、複数の円を、円状に描きだす、ということの必要があって取り組みました。

「どうやったらx座標,y座標を割り当てていけるだろう?」としばし悩み、高校時代に挫折したsin,cosをふと思い出しました。
さっそく調べると、PHPにはsin(),cos()という便利な関数があり、ネットで少々勉強したら、かなり便利なものと判明。
高校時代の挫折は、sin,cosの使い道が分からないことに大きな原因があったんだな、としみじみ。。。
今回、sin,cosでY座標、X座標を取得したい、という理由がはっきりしていたので、

やっとsin,cosの使い道が分かりました(笑)。


色々試して、以下のようなコードで、実験作第一号は無事表示。
ありがたや。。

そういえば、deg2rad()関数が必須でした。数値の角度からラジアン値に変換してくれるすぐれもの。この関数でやっと、30度ずつ描画、といった均等配置が実現しました。ありがたや。。


<?php

    $r=100;
    $img = imagecreate(500, 500);
    $bg=imagecolorallocate($img,0,0,0);

for($i=0;$i<12;$i++){
   $rad=deg2rad($i*30-90);
    $c=$i*20+15;
    $c2=255-$c;
    $y=$r*sin($rad);
    $x=$r*cos($rad);
    $y2=$y+200;
    $x2=$x+200;    
    $col=imagecolorallocate($img, $c2,$c, 0);    
    imagefilledellipse($img, $x2, $y2, 20, 20, $col);
} 

    header("Content-Type: image/png");
    imagepng($img);

?>

GDで複数図形の描画でのつまづき

GDを使って、for文で複数の円を描画させようとしたら、一個しか描画されず悩みました。
理由は簡単でした。    imagepng($img); でPNG画像を排出する部分を、for文の中に入れていたからでした。。(^^;
複数の画像を描画するにしても、描きだすPNGファイルは一枚だけ、ということで、for文に入れ込んではいけませんでした。