Challenge4Lifeでタグ「php」が付けられているもの

とあるシステムを構築中にハマった体験を。


javascript内でPHPをパラメタ付きで呼び出すのですが、Firefoxでは正常に動作するも、IE9では正常に動作しない。
パラメタには日本語を含めていました。
なぜ???
いろいろと調べた結果、文字コードの問題でした。
HTML,PHP,javascript全てUTF−8で記述しているのですが、パラメタを渡すとSJISとして渡ってしまう。
うーん、metaタグとかscriptタグにcharset="UTF-8"を付加してるのになぜ。

結局、javascript内で以下のような記述をすることでIE、Firefoxともに同じ動作をするようになりました。
var Str = encodeURIComponent(文字列);

原因がわかるのに、苦労しました(--;)

CentOS 5系でyum install php でインストールした場合にはPHP5.1.6がインストールされる。

別にプログラム自体は問題なかったのだけど、phpmyadminの最新版は対応していない。

そこで、PHP5.2以上をインストールしなければ。

そのときに、やったことをメモ。


# rpm --import http://www.jasonlitka.com/media/RPM-GPG-KEY-jlitka # vi /etc/yum.repos.d/utterramblings.repo
[utterramblings] name=Jason's Utter Ramblings Repo baseurl=http://www.jasonlitka.com/media/EL$releasever/$basearch/ enabled=0 gpgcheck=1 gpgkey=http://www.jasonlitka.com/media/RPM-GPG-KEY-jlitka priority=0

最期の行のpriority=0を設定

# yum --enablerepo=rpmforge --enablerepo=utterramblings update php

終わったらrpmforgeとutterramblingsはenabled=0に設定。

FPDFで出力したPDFを印刷したときに、フォントが違うので悩まされました。
Windowsだと、近いフォントで出力されますが、Macだと少し違うフォントで出力されます。
と、言うかインストールされているフォントによって異なります。
調べた結果、印刷するときにはコンピュータにインストールされているフォントが使われいるみたいです。
PDFで表示されているから、そのまま印刷されるだろうと思ってました。


原因は、FPDFで出力したPDFのフォントがコンピュータにないからです。
FPDFのjapanese.php内のフォント指定が"KozMinPro-Regular-Acro"となっています。
これは、標準での設定だったと思います。
これを、"KozMinPr6N-Regular"に変更すると表示と同じ印刷結果になりました。


この"KozMinPr6N-Regular"というのは、Adobe Reader Xに組み込まれているものですが、バージョンが上がると変わるかもしれないので注意が必要です。

PHPなどで、処理を実行するときに長時間の処理となってしまう場合、ブラウザ側でタイムアウトとなってしまい継続処理がうまく実行できない場合があります。

定期的にパケットを送信してタイムアウトにならないように対策をしますが、それでも対応できない場合にブラウザのタイムアウトの設定を調整します。定期的にパケットを送信してタイムアウトにならないように対策をしますが、それでも対応できない場合にブラウザのタイムアウトの設定を調整します。

Firefoxについては、アドレスバーにabout:configと入力することで設定画面を開くことが出来ます。

表示された項目のnetwork.http.keep-alive.timeoutという項目がタイムアウト時間にあたります(秒数指定)。

PHPで、四則演算をすることって多々あると思います。

その中で、小数点を含む計算をしたときに、コンピュータは賢いようで賢くないので、誤計算をしてしまいます。

例えば、
(0.1 + 0.7) * 10
答は、8なのですが、
コンピュータが出した答は7

おいおい、ってなるんですよね。

PHPだと、bcadd()関数を使って計算しないとダメなのです。
乗算の場合は、bcmul()関数。


ところが、いろいろとやっているうちに、同じ計算をしているのに現象が起きるページと起きないページがあるんです。

なぜか?

違いを見比べて見たところ、
現象が起きているページ→計算結果を直接出力している。
現象が起きていないページ→計算結果を変数に格納してから、出力している。
PHPのバージョンかもしれませんが、私の環境下ではこのような結果になりました。

結論:
計算結果は、一度変数に格納してから、出力するといい。

もしかすると、特定の環境下という条件かもしれません。

詳しい情報お持ちの方は、ご教授下さい。

PHPでファイルの内容を読み取りデータベースにインポートするプログラムを構築していたのですが、ファイルのエンコードが不明だったので、mb_detect_encodingを使ってエンコードを調べてから、処理をすることにしていました。

しかし、mb_detect_encodingの返り値がFALSEしか返ってこない。
なぜ??

調べてみると、
mb_detect_order('auto');
print_r(mb_detect_order());
を実行。

すると、結果は
. Array ( [0] => ASCII [1] => UTF-8 ) bool(false)
ん?

ASCIIとUTF-8しかない。

テストで取り込んでいたテキストは、EUCとSJIS。

納得。

PHPのmail関数を使って、日本語(マルチバイト)のファイル名を添付するしてメールを送信する方法を紹介します。

方法はいたって簡単でした。

普通に日本語ファイル名をそのまま記述すると、拡張子が外れた状態で受信してしまいます。

そこで、一つおまじないをかけます。

日本語ファイル名に対して、mb_encode_mimeheader()関数を使ってエンコードするだけです。

例:$mail_body .= "Content-Disposition: attachment; filename=\"".mb_encode_mimeheader("ファイル名").".【拡張子】\";\n";

もしかしたら、間違っているかもしれませんが、私の環境下では正常に送信・受信できました。

PHPのmail関数を使って、複数のファイルを添付してメールを送信する方法を紹介します。

// メールヘッダ部
$header="From:".【メール送信元】."\n".
       "MIME-Version: 1.0\n".
       "Content-Type: multipart/mixed;".
       " boundary=\"__BOUNDARY__\"\n\n".
       "Mime-Version: 1.0\n".
       "Content-Type: text/plain; charset=ISO-2022-JP\n".
       "Content-Transfer-Encoding: 7bit";

// メール本文部
$mail_body="メール本文\n".
"--__BOUNDARY__\n";

// 添付ファイル部
$temp_file_body ="";

// 添付ファイル1
$file1_name="【添付ファイルパス】";
$file = fopen($file1_name,"r");
$file1_contents=file_get_contents($file1_name);
fclose($file);
// 添付ファイル2
$file2_name="【添付ファイルパス】";
$file = fopen($file2_name,"r");
$file2_contents=file_get_contents($file2_name);
fclose($file);
// 添付ファイル3
$file3_name="【添付ファイルパス】";
$file = fopen($file3_name,"r");
$file3_contents=file_get_contents($file3_name);
fclose($file);

// 添付ファイル1の記述
$temp_file_body .="Content-Type: application/octet-stream;name=\"【添付ファイル1名】\";\n";
$temp_file_body .= "Content-Disposition: attachment; filename=\"【添付ファイル1名】\";\n";
$temp_file_body .= "Content-Transfer-Encoding: base64\n\n";
$temp_file_body .= chunk_split(base64_encode($file1_contents)) . "\n";

// 区切り
$temp_file_body .= "--__BOUNDARY__\n";

// 添付ファイル2の記述
$temp_file_body .="Content-Type: application/octet-stream;name=\"【添付ファイル1名】\";\n";
$temp_file_body .= "Content-Disposition: attachment; filename=\"【添付ファイル1名】\";\n";
$temp_file_body .= "Content-Transfer-Encoding: base64\n\n";
$temp_file_body .= chunk_split(base64_encode($file2_contents)) . "\n";

// 区切り
$temp_file_body .= "--__BOUNDARY__\n";

// 添付ファイル3の記述
$temp_file_body .="Content-Type: application/octet-stream;name=\"【添付ファイル1名】\";\n";
$temp_file_body .= "Content-Disposition: attachment; filename=\"【添付ファイル1名】\";\n";
$temp_file_body .= "Content-Transfer-Encoding: base64\n\n";
$temp_file_body .= chunk_split(base64_encode($file3_contents)) . "\n";

// 結合
$send_mail_body=$header.$mail_body.$temp_file_body;

// 文字エンコードをJISに変換
$send_mail_body=mb_convert_encoding($send_mail_body,'JIS');

// 文字エンコードをJISに変換
$subject=mb_convert_encoding("メール件名",'JIS');

// メール送信
mail(【メール宛先】,$subject,$send_mail_body,$header);

とある事情でMySQLを4.0.26から5.1.4にバージョンアップするこになったのですが、問題が山積みでこまっています。
同じMySQLだから、互換性はあるだろうとたかをくくっていいたので、出鼻をくじかれっぱなし。

その中の一つを紹介します。
MySQL4.0.26に格納されいるデータを移行しようとしたのですが、エラーが出てどうしても挿入できないということでした。
エラー内容は、Field '%s' doesn't have a default value というようなエラーで、ググッてみるとすぐに解答は見つかりました。
ただ、根本的な解決になるかは不明ですが。
my.iniの【sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"】という項目をコメントアウトすることで解消。

他にも、MySQL5.1系は日付のチェックをしてくれる親切設計なのですが、既存データには2007-02-29などのありえない日付が格納されている。これも丁寧にエラーとしてはじかれます。
ただ、ユーザ側でMySQLのエラーを表示するわけにもいかないので、事前にPHP側で日付の整合性をとることにして解決。

それにしても、速度的には4.0.26のほうが快速だと個人的には思うのですが、テーブル毎のファイル分割をしたいがために、こんなに手間になるなんて。

とある、メーリングリストに4.0.26、4.1系、5.1系の中でどれか軽快で速度が速いですがという質問をしたのですが、「最新版にしなさい」と言われorz
質問に対しての答えではない。
今後のこともあるので、最新版をチョイスして開発をすることに。

あー、バージョンアップなんてめんどくさいって思うことで、SEやってるんだなって実感を覚えました。

プログラムを構築していて、どーしてもエラーが出る箇所ってないですか?
エラーが出るのは分かっているんだけど、別に無視できるエラーだったり。
でも、PHPの仕様で絶対発生するエラー。

こんなときには、「@」を使います。
エラーが出る箇所の先頭に@をつけてあげるだけで、エラーを無視できます。

ちなみにこの「@」はエラー制御演算子と言います。
エラー制御できないのは、関数の定義、クラスの定義、条件構造などです。

エラーが発生しないのが、一番いいですけどね。

書いたスクリプトが@だらけにならないよーに注意しましょう。  

PHPのSEO対策

PHP・MySQL
|
PHPでWEBサイトを構築したときに一番頭を抱えるのがSEO対策についてです。
システムとして成立しないといけない上に、SEO的に有利なサイトを構築しないと無意味です。
特にショッピングカートシステムなんかは、集客の為にSEO対策が必須なのでかなり頭を悩まされます。

PHPでWEBサイトを構築したらURLにhttp://www.sample.com/sample.php?a=100&b=abcとなってしまうことがありますよね。
これは、SEO的には不利だと言われています。
なので、一般的にはhttp://www.sample.com/100/abc/sample.htmlのURLからrewriteしていることが多いのではないかと思います。

しかし、調べてみると事実は違っていました。

「動的URLも静的URLと同様に扱う」 - Google Matt Cutts氏
まさに、目からうろこと言った状態。
果たしてこの真意がどうなのかは知る術がないので、一概にURLをそのままにするはどうかと思いましたが、とりあえずこういうこともあるのだと頭に置いておくと気休めにはなるのではないかと思います。  

PHPで携帯サイトを構築することになったのですが、携帯の小さい画面でPCサイトと同様の文字を
表示するとわずらわしくてしょうがありません。
そこで絵文字を使って表現することにしたのですが、携帯のキャリアごとに絵文字のコードがあるんですよね。
そこで絵文字変換スクリプトを作ってみました。


PHPで初期のころに悩まされたエラーの話です。

とあるシステムを開発していて「Warning:Cannot modify header information-headers already sent by  ・・・・・」エラーが発生しました。

今となってはエラーを見れば原因はすぐに分かるのですが、(今さらエラーを出すスクリプトを書く時点でおかしい話ですが)ググッてみれば結構検索にはひっかります。

みなさん同じような悩みを抱えているようで。

さて、原因はheader()の前に何かしらの文字を出力してるのが原因です。

例えば、デバッグ中のダンプする処理がそのまま残っていたり、全角のスペースが入力されていたり。

このエラー自体を無視する方法は、

php.iniで[output_buffering = ON]とするか、スクリプトの最初にob_start()を呼び出す。

 

いろいろと悩んで成長していくんですよね。

まさに失敗は成功の母と言ったところでしょうか。

MySQLって軽快な動作で、検索が早いと評判ですがどうしてもレコード数の増加、並び替えの必要な場合など、処理によっては異常に処理時間が長くなることはないですか?
処理時間の長いクエリは、システムとしては欠陥クエリなんですけど、そこは置いておいて。

ORDER BY句で並び替えをした場合のSQL文をExplainで確認してみると、ExtraにUsing filesortという表示が出た場合の話です。
この表示が出た場合、SQLクエリの処理に時間がかかります。レコード数に比例して。
とあるシステムで、検索に失敗することがありました。
開発環境ではレコード数が少ないので異常はなかったのですが。
「Got error 28 from table handler」が表示されます。


結構前の話なんですが、PHP5.0.4でとあるシステムを構築していました。
開発初期の段階では最新版でした。
仮納品したあと、とある問題が発生しました。
データベースのレコード数が増えてきたため、データをエクスポートするのに失敗している現象が発生。
エクスポートにはCSV形式とExcel形式での出力に対応していたのですが、なぜか2MBちょうどしかダウンロードされないのです。
プログラムの見直し、Apache、PHP、通信経路などさまざまな要因を探りました。
かなり悩んでいましたが、原因は意外なところにありました。
PHPのバージョンです。
そのときには、5.1.6が最新でした。
どうも、5.0.4だと上記のような現象が発生するらしく、バージョンアップすることで解決しました。

定期的なバージョンアップって必要なんですね。

javascriptの限界??

PHP・MySQL
|

とあるPHPで表示したWEBページ内の文字をjavascriptで検索するように設定していて、ある行を境に検索できなくなりました。

ページ内検索のjavascirptは以下のとおり。

var fFirst; //はじめかどうかのフラグ
var objRange; //TextRangeオブジェクト
//検索関数
function Start()
{
    objRange = document.body.createTextRange();
    //文字列が空であれば終了
    if (document.search_form.txtWord.value.length == 0)
    {
        return;
    }
    strCheck = document.search_form.txtWord.value;
    if (fFirst)
    {
        fFirst = false;
    }
    else
    { //2度目以降
        objRange.move("character", 1);
    }
    //セレクトする
    if (objRange.findText(strCheck))
    {
        objRange.select();
        objRange.scrollIntoView();
    }
}

 

という感じ。

PHPでWEBページを表示しているんですけど、HTMLタグやらでソースは5万行を超える状態。

この5万行が限界らしく5万目は見事に検索されなくなりました。

49999行目までは検索できるんですけど。

どなたか何か情報もってないですか??

PHPでWEBアプリを開発していく上で、HTMLは必須だと思います。

HTMLと一緒にCSS(スタイルシート)についても覚えておくべきだと思います。

さて、PHPで開発していて内部的な処理はほぼ対応できるのですが、ユーザビリティを考えるとjavascriptも一緒に覚えておくべきだと思います。

ブラウザ上での処理をPHPだけで行おうとすると、どうしても操作面で使いにくいものになってしまいます。

そこで、javascriptについて勉強をするんですが私の場合、サンプル集を参考に自分なりに修正して使っています。

javascriptで大掛かりな処理はまだできませんが、簡単な処理であればサンプル集の簡単なものをアレンジして使用したので十分かなと。

現在手元においてるのがこれです。



内容は、基本的なものはほとんど抑えているので重宝してます。

細かい説明はないですけど、サンプルのコードを見ているとなんとなく理解できます。

サンプル自体が簡単な機能なので、コードも短めです。

 

今後は、Ajaxについても手をつける必要があるんですけどね。

 

MySQLで数字のソート

PHP・MySQL
|
MySQLを使っていて抽出したデータを並び替えるというのはごく一般的に使われると思います。
例えば、INT型のカラム名Aというものを昇順にならび替える場合はSQL文に
「 ORDER BY A 」と追記してあげれば正常な結果が出てきます。
ただ、私の場合はVARCHAR型のカラム名Bのデータを昇順に並び替える必要が出てきたことがあります。
単純にORDER句を使えば正常な結果が出てくるのですが、そのBに入っているデータは数字であったり文字であったりしています。
例えば、「第1号」とか「第234号」とか。
この並び替えをORDER句を使って実行すると先頭からの文字でソートされてしまいます。
1「第1号」
2「第11号」
3「第111号」
4「第2号」
という感じです。
これを、番号順に並び替えるにはどうすればいいか。

答えは、桁数順→数字順とすれば正常に抽出されます。
SQL文では「SELECT * FROM table ORDER BY LENGTH(B)、B」
という感じです。
LENGTHでカラムBの文字数順に並び替えてくれます。

ただ、一点未解決の部分がありまして、「第10−1号」の場合はどうするか?
これは、PHP側でデータを取り込む際もしくは、抽出したデータを再度並び替えすることで対応しました。

PHP入門したあとは・・・・

PHP・MySQL
|

PHPの入門書を紹介しましたが、入門したあとに手にしておいた本はこれです。

「PHP ポケットリファレンス」

このシリーズは結構役に立っています。

「なんだ、そんなの買わなくてもWEBで探せばあるよ」って思っている人もいるでしょう。

でも、WEBページよりもアナログ的な紙ベースの方が格段に探しやすいです。

ただ、紙ベースの難点は更新されないことぐらい。

入門したあと、自分でプログラムを考えて構築するには是非片手に持っていて損はないと思いますよ。

 

PHP入門書

PHP・MySQL
|

私はもともとプログラムの経験はほとんどなく学生時代にC言語をかじった程度でした。

今は主にPHPを使っているのですが、独学です。

そんな入門書として最適なのが

最初は10日でほんとにって感じですが、意外に簡単に覚えることができます。

なにより段階を踏んでいるのと、難しいところは無視しているような内容が挫折しないで読める、試せるという感じでした。

あくまで入門書なので「PHPとは」という触りの部分だけですが、とっかかりは非常によかったです。

これからPHPを独学で始めてみようという人にはオススメです。

カスタム検索

ioPLAZA【アイ・オー・データ直販サイト】 ioPLAZA【アイ・オー・データ直販サイト】
あれもこれも標準装備のレンタルサーバ あれもこれも標準装備のレンタルサーバ


Web広告限定ストア(eクーポン)Web広告限定ストア(eクーポン)

問い合わせ

メールフォーム