※ パクレゼルヴではWeb開発エンジニアを大募集中!詳細はこちら

htmlメール  

2010/7/1 木曜日 3:54:13

おいすー^^

とかやってみる

こんばんは のびーにょです

HTMLメールについて

phpでHTMLメールを送る場合、

//送信元アドレス
$from "";
//BCCアドレス
$bcc ="";
//タイトル
$title ="";
//本文
$body ="";
//エラー時の戻り先
$replay="";

mb_language('Japanese');
mb_internal_encoding("UTF-8");
mb_detect_order("ASCII, JIS, UTF-8, EUC-JP, SJIS");
$header = "FROM: ".$from."\n";
$header.= "BCC: ".$bcc."\n";
$header.= "Return-Path: ".$from."\n";
$header.= 'MIME-Version: 1.0' . "\n";
$header.= "Content-Type: text/html; charset=ISO-2022-JP";

$title = mb_convert_kana($title,"KV");
$body = mb_convert_kana($body,"KV");
$body = mb_convert_encoding($body, 'JIS', 'auto');

mb_send_mail($mail,$title,$body,$header,"-f ".$replay);

ってやってやればbodyにhtml書けば送れるらしいよ。

$header.= 'MIME-Version: 1.0' . "\n";
$header.= "Content-Type: text/html; charset=ISO-2022-JP";

要するにヘッダーに上記を追加してやれば良いと言う話。
text/plainじゃなくてtext/htmlにしてやるべし。
MIMEもお忘れなく。

まぁPEARのMailとか使ったほうがいいけど。

と、まぁそんなことは割とどうでもよくて。

CSSで背景指定した場合

background-image:url(hogehoge);

とかね

HTMLメールだと背景画像が表示されないらしい。
主にhotmailとGmail

と、言うことで、じゃぁどうしようか ってなる。

ここで懐かしのテーブル背景!

<table background="hogehoge">

って奴

これならhotmailでもGmailでも背景として画像が使えるらしい

初めて知った

まぁ携帯ばっかり作ってたのでHTMLメールは知らないのです。

携帯のHTMLメールはマルチパート部分が結構複雑な上にキャリアでちょっと違う部分もあるので注意です。

機会があればそのへんも書きたいと思います。

のびーにょ HTMLとか, PHP

sessionについて  

2010/6/30 水曜日 18:54:04

はじめまして。
6月からソリューション事業部にお世話になっております。
よろしくお願い致します。

基本的なことですが、sessionについて悩んだことを書きます。

下記の処理を実行するとエラーがでます。
問題点はセッションに値が入ってないからです。
session_start関数を呼べば$_SESSIONに値を入れなくても
エラーなく判定できると思い込んでいました。

session_start();

if(strcmp($_SESSION['proposal']['complete'],'test') == 0){
}

対処法は下記のようにセッションに値をいれておくか
array_key_existsなどの関数を使うことにより、
エラーなく実行することができます。

$_SESSION['proposal']['complete'] ='';

または

if(array_key_exists('proposal', $_SESSION) &&
    array_key_exists('complete', $_SESSION['proposal']) &&
      strcmp($_SESSION['proposal']['complete'],'test') == 0){
}

Manocchi PHP

PHPのガーベジコレクタについて  

2010/6/30 水曜日 16:48:12

PHP 5.2までのガーベジコレクタは参照カウント方式です。
循環参照が発生すると、その参照に含まれるオブジェクトが回収できませんので、デーモンなど長時間実行するようなスクリプトを作る場合は循環参照を起こさないように注意する必要があります。

尚、PHP 5.3からは循環参照コレクタが使え、デフォルトで有効になっています。
実際にPHP 5.1.6と5.3.0を比較し、実際にどのような動きになるか以下のコードで試してみました。

< ?php

ini_set('memory_limit', -1);
// gc_disable();

class A
{
}

$loop_count = 1000000;
for($i = 1; $i <= $loop_count; $i++)
{
    $a = new A;
    $a->self = $a; // 循環参照
    if (($i % round($loop_count / 10)) ==  0)
    {
        printf("%10d: %10d KB\n", $i, memory_get_usage() / 1024);
    }
    // unset($a->self);
}

if ( function_exists('memory_get_peak_usage') )
{
    // (PHP 5 >= 5.2.0)
    printf("max %10d KB\n", memory_get_peak_usage() / 1024);
}

PHP 5.1.6の場合

PHP 5.1.6だと、以下のような結果になります。
循環参照されている状態だと、どんどん増え続けます。

$ php mem_test.php
    100000:      31947 KB
    200000:      63872 KB
    300000:     101942 KB
    400000:     127723 KB
    500000:     153504 KB
    600000:     203861 KB
    700000:     229643 KB
    800000:     255424 KB
    900000:     281205 KB
   1000000:     306986 KB

unsetの所のコメントアウトを外して開放するようにすると以下のような結果になります。
循環参照されていないので、メモリの開放は正しく行われます。

    100000:        622 KB
    200000:        622 KB
    300000:        622 KB
    400000:        622 KB
    500000:        622 KB
    600000:        622 KB
    700000:        622 KB
    800000:        622 KB
    900000:        622 KB
   1000000:        622 KB

PHP 5.3.0の場合

PHP 5.3.0の結果。一定以上から変化しません。
循環参照コレクタがうまく働いているようです。

$ php mem_test.php
    100000:       1582 KB
    200000:       1582 KB
    300000:       1582 KB
    400000:       1582 KB
    500000:       1582 KB
    600000:       1582 KB
    700000:       1582 KB
    800000:       1582 KB
    900000:       1582 KB
   1000000:       1582 KB
max       5139 KB

循環参照コレクタの有効/無効の変更はgc_enable/gc_disable関数で行います。
gc_disableの所のコメントアウトを外すと、PHP 5.3.0でもメモリが増え続けます。

$ php mem_test.php
    100000:      43125 KB
    200000:      85692 KB
    300000:     136451 KB
    400000:     170827 KB
    500000:     205202 KB
    600000:     272345 KB
    700000:     306720 KB
    800000:     341096 KB
    900000:     375471 KB
   1000000:     409846 KB
max     409863 KB

尚、gc_collect_cycles関数で強制的にガベージを収集することができますが、gc_disableで循環参照コレクタを無効にしている時に確保したメモリは収集されないようですので、わざわざ無効にする必要はないと思います。
また、gc_collect_cycles関数を使うと、わずかながらメモリが増えていく現象が見られましたので、ガベージの収集も基本的にはPHPに任せるようにした方が良いようです。

当然正しく開放されるようにプログラムを組むべきですが、デーモンのように長時間実行されるようなスクリプトを作る場合、石橋を叩いて渡るなら5.3以降を使うようにした方が良さそうです。

個人的な意見としては、開発時はgc_disableで開発し、テスト・運用時にgc_enableで動かすのが良いのではないかと思います。

マカー PHP

久々にベタ書きで入力フォームを書いてみる  

2010/6/30 水曜日 15:47:47

モリモリモリモリです。

Webアプリは実際の業務ではCakePHP、symfony、Zend Framework等のPHPフレームワーク、
自社フレームワーク、またテンプレートエンジンとしてsmarty等を使うかと思います。

WEBプロミングを始めたばかりの人は何を参考にすればいいか割と苦労するかなと。
私自身がそうでした。

ベタ書きで簡単な入力フォームを書いたらどーなるかなと思って久々に書いてみることにしました。

以下は、セッションを利用したPC向けの書き方です。
手抜きな部分も有りますので参考程度にお願いします。

< ?php
session_start();

$param = array('name','tel');
foreach($param as $val){
	// SESSION値よりもPOST値を優先
	if(isset($_POST[$val])){
		${$val} = trim($_POST[$val]);
	}elseif(isset($_SESSION[$val])){
		${$val} = trim($_SESSION[$val]);
	}else{
		${$val} = '';
	}
}

// 確認ボタンが押された際の処理
if(isset($_POST['confirm_btn'])){
	// バリデーション
	$err = array();
	foreach($param as $val){
		switch($val){
			case 'name':
				if($name == ''){
					$err['name'] = '※名前は必須です。<br />';
				}
				break;
			case 'tel':
				if($tel == ''){
					$err['tel'] = '※電話番号は必須です。<br />';
				}elseif(!preg_match('/^\d+$/',$tel)){
					$err['tel'] = '※電話番号は数字で入力して下さい。<br />';
				}
				break;
			default:
		}
	}
	// エラーが無ければ
	if(count($err) == 0){
		// 値をセッションに格納
		foreach($param as $val){
			$_SESSION[$val] = ${$val};
		}
		// 確認画面へロケート
		header('Location:http://example.com/confirm.php');
		exit;
	}
}
?>
<html>
<body>
<form method="post" action="">
	< ?php
	if(isset($err['name'])){
		echo $err['name'];
	}
	?>
	名前: <input type="text" name="name" value="<?php echo htmlspecialchars($name); ?/>" /><br />
	< ?php
	if(isset($err['tel'])){
		echo $err['tel'];
	}
	?>
	電話番号: <input type="text" name="tel" value="<?php echo htmlspecialchars($tel); ?/>" /><br />
	<input type="submit" name="confirm_btn" value="確認" />
</form>
</body>
</html>

投稿の際に勝手に置換されたりするので、上記のコードをまんまコピペしてもうまく動きません。汗
適宜修正お願いします。
すいません。

5行目あたりからの処理の

${$val}

ですが、こんな感じで可変変数を使うことにより、$name、$telに入力値が入ってくるようになります。

これについては弊社の下記記事も参考にどうぞ。
http://labs.pakureserve.jp/archives/124

バリデーション処理もベタで書いてますがご了承下さい。

処理としては、エラーが無ければセッションに格納して、確認画面へロケーション。
確認画面ではセッションの値を表示
(表示の際は項目に応じてhtmlspecialchars、nl2br関数等を使って表示させましょう)し、
登録完了画面で登録が完了したら、

$_SESSION = array();

等でセッションを空にしてやる感じで。

あと、最近たまたま気付いたことですが、もしこのフォームのテキストフォームが一つだった場合、
IEでテキストを入力してENTERキーを押すと、多分動きません。笑

これはIEのバグ?

IEでテキストフォームが一つの場合、ENTERキーでSubmitした場合に、
なぜか type=”submit” のパラメータと値がpostされないのです。
つまり、この場合だと、$_POST['confirm_btn']のパラメータと値が送信されません。

これを回避するためには以下のようなテキストフォームをダミーで入れといてやれば大丈夫です。

<input type="text" style="display:none;" />

…美しくない!

MoriMoriMoriMori HTMLとか, PHP

コーディングルール  

2010/6/8 火曜日 17:35:14

皆さん、コードを書くときコーディングルールを気にしますか?
自分は気にしてませんダメな人ですね。

ということで、好きなフレームワークCodeIgniterの例にならって、まとめ的に書きとめようと思う。

◆クラス名・メソッド名
クラス名は常に最初の文字を大文字にしなければいけません。コンストラクタメソッドはクラス名と同じにします。
メソッド名は、すべて小文字にして動詞など含めてわかり易い名前にするべきです。

間違い:
class superclass
class SuperClass

正しい:
class Super_class

間違ったメソッド名と正しいメソッド名

間違い:
function fileproperties()		// 表現がわかりにくく、アンダースコアが抜けている
function fileProperties()		// 表現がわかりにくく、キャメルケースが使われている
function getfileproperties()		// ベター! しかしながら可読性に欠ける
function getFileProperties()		// キャメルケースが使われている
function get_the_file_properties_from_the_file()	// 長過ぎる

正しい:
function get_file_properties()	// 説明的、アンダースコア、全て小文字

◆変数名
変数名はクラス名とほぼ同じ。「$p」とか単語になっていないものはループ変数のみにつかいます。

◆定数
定数は変数とほぼ同じ。だけど、例外として大文字のみを使用します。

◆TRUE、FALSE、NULL
常に大文字を使用します。

◆論理演算子
「||」は解像度の低いデバイスでは良く見えなく「11」に見えてしまうことがあることから「OR」を使用する。

間違い:
if ($foo || $bar)
if ($foo AND $bar)  // 問題無いがアプリのシンタックスハイライト機能にはお勧めできない
if (!$foo)
if (! is_array($foo))

正しい:
if ($foo OR $bar)
if ($foo && $bar) // 推奨
if ( ! $foo)
if ( ! is_array($foo))

◆インデント
Allman スタイルのインデントを利用します。クラス宣言を除いて、括弧は常に1行に単独で配置し、その制御ステートメントと同じ深さにインデントします。

間違い:
function foo($bar) {
	// ...
}

foreach ($arr as $key => $val) {
	// ...
}

正しい:
function foo($bar)
{
	// ...
}

foreach ($arr as $key => $val)
{
	// ...
}

◆括弧の前後のスペース
一般的に、括弧の前後にはスペースを追加すべきではありません。
例外として、括弧内に引数を記述する PHP 制御構造(if,switch,for,while等)では、関数と区別しやすくしたり可読性を高めるために、常にスペースを配置すべきです。

間違い:
$arr[ $foo ] = 'foo';

正しい:
$arr[$foo] = 'foo'; // 配列のキーの前後には空白を入れません

間違い:
function foo ( $bar )
{

}

正しい:
function foo($bar) // 関数定義の括弧の前後には空白を入れません
{

}

間違い:
foreach( $query->result() as $row )

正しい:
foreach ($query->result() as $row) // PHPの制御構造の後ろには空白を1つ入れますが、中の括弧には入れません

◆PHPエラー
コードはエラーを起こさず、潜在的なWARNINGやNOTICEもなく動作するようにしましょう。
例えば、最初にisset()で確かめずに($_POST配列のキーのような)未定義の変数を使わないようにしてください。

あくまでチラシの裏ですので、人それぞれのコーディングルールなので、特に決まりごとが無ければやりやすい方法でやるべきかとー。

下音タヌキ PHP