SQLの窓

2017年09月02日


FormData を使用して $.ajax で送信すると、ファイルのアップロードとメール送信(ファイル添付)を一度に行えます

mb_send_mail による メール送信におけるファイル添付の普通のサンプルはこちら

呼び出し
	$( "#base" ).submit(function( event ) {

		event.preventDefault();

		$("#action").prop( "disabled", true );
		$("#action_copy").prop( "disabled", true );
		
		// 新規送信用オブジェクト
		var formData = new FormData();

		// 入力テキスト
		formData.append("fld_to", $("input[name='fld_to']").val() );
		formData.append("fld_subject", $("input[name='fld_subject']").val() );
		formData.append("fld_body", $("textarea[name='fld_body']").val() );
		// ファイルオブジェクト( type="file" )
		formData.append("fld_file", $("input[name='fld_file']").get(0).files[0]);

		$.ajax({
			url: "app-mail.php",
			type: "POST",
			data: formData,
			processData: false,  // jQuery がデータを処理しないよう指定
			contentType: false   // jQuery が contentType を設定しないよう指定
		})
		.done(function( data, textStatus ){
			console.log( "status:" + textStatus );
			console.log( "data:" + JSON.stringify(data, null, "    ") );

			if ( data.status == 0 ) {

				toastr.info("メールが送信されました");

				$("input[name='fld_subject']").val( "" );
				$("textarea[name='fld_body']").val( "" );

			}

			if ( data.status == 1 ) {
				// エラーメッセージを表示
				toastr.error("メール送信に失敗しました");

			}
			
		})
		// 失敗
		.fail(function(jqXHR, textStatus, errorThrown ){
			console.log( "status:" + textStatus );
			console.log( "errorThrown:" + errorThrown );
		})
		// 常に実行
		.always(function() {

			$("#action").prop( "disabled", false );
			$("#action_copy").prop( "disabled", false );

		})
		;		
	
	});

受け側の PHP

$_POST['fld_body'] の中身は UTF-8 ですが、mb_send_mail が変換してくれます。
<?php
// ***************************
// このアプリ特有の定義
// ***************************
require_once("../mail-jquery/app.model");

$GLOBALS["content_type"] = "application/json";
$GLOBALS["upload_dir"] = "./upload";

require_once("{$GLOBALS["common_path"]}common.php");

// type="file" のフィールドの name の値
$fld = "fld_file";

// ******************************************************
// アップロード 処理
// ******************************************************
if ( !$_FILES ) {
	// php.ini の upload_max_filesize を超えて、
	// Apache に制限が無いと $_FILE が空になる
	$_FILES[$fld]['error'] = 5;	// ユーザエラーメッセージ
}

// *************************************
// アップロード処理
// フィールド名 : $fld で固定
// *************************************

// true では実行しない
if ( !$GLOBALS["debug_update"] ) {

	$upload = realpath ( $GLOBALS["upload_dir"] );
	$upload .= ( DIRECTORY_SEPARATOR . $_FILES[$fld]['name'] );
	if ( move_uploaded_file(
		$_FILES[$fld]['tmp_name'], $upload ) ) {
		$_POST['result']  = "アップロードに成功しました";
	}
	else {
		if ( !$_FILES ) {
			$_FILES[$fld]['error'] = 5;	// ユーザエラーメッセージ
		}
		$_POST['result']  = "アップロードに失敗しました";
	}

}
else {
	if ( $_FILES[$fld]['error'] == 0 ) {
		$_POST['result']  = "アップロードに成功しました";
	}
	else {
		$_POST['result']  = "アップロードに失敗しました";
	}
}


$_POST['files'] = $_FILES;

// *************************************
// メール処理
// *************************************
mb_language("Japanese");
mb_internal_encoding("UTF-8");

$uniqid = uniqid();

$from_header = "From: " . mb_encode_mimeheader( mb_convert_encoding("差出人","iso-2022-jp") );

// このソースを置くサーバから使えるメールアドレス
$from_header .= " <{$GLOBALS["mail"]}>\n";
$from_header .= "Content-Type: multipart/mixed; boundary=\"{$uniqid}\"\n";

$mime = $_FILES['fld_file']['type'];
$fname = $_FILES['fld_file']['name'];

$body  = "--{$uniqid}\n";
$body .= "Content-Type: text/plain; charset=\"ISO-2022-JP\"\n";
$body .= "\n";
$body .= $_POST['fld_body'] . "\n";
$body .= "--{$uniqid}\n";
$body .= "Content-Type: {$mime}; name=\"{$fname}\"\n";
$body .= "Content-Transfer-Encoding: base64\n";
$body .= "Content-Disposition: attachment; filename=\"{$fname}\"\n";
$body .= "\n";

// アップロードされたファイル
$path = $upload;
$data = file_get_contents($path);
$encode = base64_encode($data);

$body .= chunk_split($encode);
$body .= "\n--{$uniqid}--\n";

if ( !$GLOBALS["debug_update"] ) {
	$result = mb_send_mail(
		$_POST["fld_to"],
		$_POST["fld_subject"],
		$body,
		$from_header );
}
if ( $result ) {
	$error = 0;
}
else {
	$error = 1;
}

// アップロードして添付したファイルを削除
unlink($path);


// ***************************
// JSON データ作成
// ***************************
$json = new stdClass;

$json->post = $_POST;			// 行データ
$json->status = $error;		// エラー
if ( !$GLOBALS["debug_update"] ) {
	$json->user = $GLOBALS["mail"];
	$json->debug = $from_header;
}

print json_encode( $json, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE );

?>

関連する記事

fake sendmail for windows を使って、PHP でごく普通に( mb_send_mail で )メール送信 : Gmail なので ssl(465)




【PHP + 通信の最新記事】
posted by lightbox at 2017-09-02 16:57 | Comment(0) | PHP + 通信 | このブログの読者になる | 更新情報をチェックする

ファイルのアップロードからそれを添付してメールを送るテンプレート(スケルトン)



メール送信部分には、『mb_send_mail』を使用しているので、インターネット上のサーバーで、そこからパスワード無しでメールアドレスが利用できる必要があります。

※ fake sendmail for windows でも動作確認しました
※ FormData を使用して送信すると、ファイルのアップロードとメール送信を一度にできます。
( FormData を使用したサンプル )



メールアドレスは、mail.php で、セッション変数にセットして使用しています。

Content-Type の MIME は、ファイルアップロード時に取得した type をセッション変数に保存して使用しています。
<?php
require_once("common.php");

$_SESSION['user'] = "セッションデータを表示する為のダミー";
$_SESSION["mail_from"] = "メールアドレス";

require_once("mail_view.php");
?>
ファイル一覧
  • common.php
  • debug_value.php
  • mail.php
  • mail_view.php
  • form2.php
  • form2_view.php
  • upload1.php
  • html_head.php
  • mail_ex.php
  • style.css ※ ソース全体参照へのリンク
  • メール送信部分の mail_ex.php
    <?php
    require_once("common.php");
    
    require_once("html_head.php");
    
    foreach( $_POST as $Key => $Value ) {
    	$_POST[$Key] = str_replace("\\\\", "\\", $Value );
    	$_POST[$Key] = str_replace("\\'", "'", $_POST[$Key] );
    	$_POST[$Key] = str_replace("\\\"", "\"", $_POST[$Key] );
    }
    
    
    mb_language( "ja" );
    mb_internal_encoding("utf-8");
    
    $from = $_SESSION["mail_from"];
    $fname = $_SESSION["mail_file"];
    $mime = $_SESSION['mime'];
    
    if ( $fname == "" ) {
    	print "ファイルをアップロードして下さい <a href=\"mail.php\">戻る</a><br>";
    	exit();
    }
    
    $uniqid = uniqid();
    
    $headers = "From: {$from}\n";
    $headers .= "Content-Type: multipart/mixed; boundary=\"{$uniqid}\"\n";
    
    $body  = "--{$uniqid}\n";
    $body .= "Content-Type: text/plain; charset=\"ISO-2022-JP\"\n";
    $body .= "\n";
    $body .= $_POST['text'] . "\n";
    $body .= "--{$uniqid}\n";
    $body .= "Content-Type: {$mime}; name=\"{$fname}\"\n";
    $body .= "Content-Transfer-Encoding: base64\n";
    $body .= "Content-Disposition: attachment; filename=\"{$fname}\"\n";
    $body .= "\n";
    
    $path = "upload_file/{$fname}";
    $data = file_get_contents($path);
    $encode = base64_encode($data);
    
    $body .= chunk_split($encode);
    $body .= "\n--{$uniqid}--\n";
    
    $ret = mb_send_mail(
    	$_POST['to_address'],
    	$_POST['subj'],
    	$body,
    	$headers );
    
    // アップロードして添付したファイルを削除
    unlink($path);
    $_SESSION["mail_file"] = "";
    
    if ( $ret === TRUE ) {
    	print "<a href=\"mail.php\">戻る</a> メール送信が終了しました。<br>";
    }
    else {
    	print "<a href=\"mail.php\">戻る</a> メール送信に失敗しました。<br>";
    }
    
    print "</body>";
    print "</html>";
    ?>
    
    
    ファイルのアップロード後、アップロードフォルダのファイルのタイムスタンプが5分以上経過している場合は削除します。(upload1.php)
    
    ファイルアップロードの実行は IFRAME 内の別ページで行っています。さらに、IFRAME 内の IFRAME にアップロード結果を表示している為、アップロード結果の『ファイル名』をメインページに転送する為、JavaScript を PHP で出力しています。
    
    その際、メインページでは jQuery を使用しているので、メインページの jQuery を使用してファイル名をテキストフィールドに転送しています
    
    if ( move_uploaded_file( $_FILES['file_1']['tmp_name'], $upload ) ) {
    	print "アップロードに成功しました<br>";
    	$_SESSION["mail_file"] = $target;
    	print "<script>";
    	print " parent.parent.$('#mail_file').val( \"{$target}\" );";
    	print "</script>";
    }
    else {
    	print "アップロードに失敗しました<br>";
    }
    
    
    関連する記事
    
    fake sendmail for windows を使って、PHP でごく普通に( mb_send_mail で )メール送信 : Gmail なので ssl(465)
    
    
    
    
    posted by lightbox at 2017-09-02 16:33 | PHP + 通信 | このブログの読者になる | 更新情報をチェックする

    fake sendmail for windows を使って、PHP でごく普通に( mb_send_mail で )メール送信 : Gmail なので ssl(465)

    PHP : mb_send_mail を使用した自家用メール送信 API では、レンタルサーバー上利用する事を想定していましたが、fake sendmail for windows を使用すると、windows 上で同じ事ができます。
    
    fake sendmail は、XAMP に同梱されているらしい情報を多くインターネット上で得る事ができますが、何故か単独で Windows で利用する上では全く無名(日本)に近いソフトウェアのようです。
    
    メールサーバは、フリーメールで可能で、簡単な設定で利用できます。以下のサンプルは、Gmail で動作確認しました。( 但し、Gmail では、Gmail 側で安全性の低いアプリの許可を『有効』にする必要があります )
    
    ▼ 手順
    
    ダウンロード
    
    配布元より、sendmail.zip をダウンロードして、解凍します。
    
    
    sendmail.exe の動作テスト
    
    まず、sendmail.ini をエディタで開いて、四つのエントリを指定します
    ▼ Gmail の場合
    
    smtp_server=smtp.gmail.com
    smtp_port=465
    auth_username=ユーザ@gmail.com
    auth_password=パスワード
    
    ▼ さくらインターネットの場合
    smtp_server=初期ドメイン
    smtp_port=587
    auth_username=ユーザ@初期ドメイン
    auth_password=パスワード
    
    ※ smtp_ssl=auto となっており、デフォルトで ssl で実行され、使え無い場合は TLS を使おうとします さらに、この中に、send_test.bat を作成して以下のように記述します( 作者のオリジナルのテスト方法です )
    @ECHO OFF
    REM send email from command line via SMTP with sendmail
    
    ECHO From: ユーザ@gmail.com > %TEMP%\temp.mail
    ECHO To: ユーザ@宛先ドメイン >> %TEMP%\temp.mail
    ECHO Subject: this is a test >> %TEMP%\temp.mail
    ECHO.>> %TEMP%\temp.mail
    ECHO testing. >> %TEMP%\temp.mail
    ECHO blah blah.. >> %TEMP%\temp.mail
    ECHO. >> %TEMP%\temp.mail
    ECHO blah. >> %TEMP%\temp.mail
    
    sendmail -t < %TEMP%\temp.mail
    
    REM DEL %TEMP%\temp.mail
    
    
    これをコマンドプロンプトより実行して、メールが届く事を確認します。最後の行を REM でコメントにしているのは、送信で使われたテキストファイルを残す為です。sendmail.exe に -t が指定されているのは、標準入力より送信データを取得する為のもので、PHP で実行する場合特に必要はありませんでした。
    
    temp.mail の内容
    
    From: ユーザ@gmail.com 
    To: ユーザ@送り先ドメイン 
    Subject: this is a test 
    
    testing. 
    blah blah.. 
     
    blah. 
    
    これは、コマンドプロンプトから実行できる事を意味しますが、PHP で使用するには、php.ini で以下のように指定するだけです。 php.ini の設定
    sendmail_path = "C:\tools\sendmail\sendmail.exe"
    
    実際の sendmail.exe のパスを "" で囲んで指定します。 ※ この場合、エラーログは "C:\tools\sendmail\error.log" です( デフォルト ) PHP のコード
    mb_language("Japanese");
    mb_internal_encoding("UTF-8");
    
    $from_header = "From: " . mb_encode_mimeheader( mb_convert_encoding("差出人","iso-2022-jp") );
    
    // このソースを置くサーバから使えるメールアドレス
    $from_header .= " <{$GLOBALS["mail"]}>";
    
    $result = mb_send_mail($_POST["fld_to"], $_POST["fld_subject"], $_POST["fld_body"], $from_header);
    if ( $result ) {
    	$error = 0;
    }
    else {
    	$error = 1;
    }
    
    
    
    PHP の mb_send_mail の使用方法の全体のサンプルは、こちらを参照して下さい。
    
    
    
    
    posted by lightbox at 2017-09-02 13:36 | Comment(0) | PHP + 通信 | このブログの読者になる | 更新情報をチェックする

    2017年09月01日


    VBScript を『管理者として実行する』には、Shell の runas ( 右クリックメニューの実行と同等 ) で実現します

    UAC によるセキュリティの影響で VBScript を使う場合、管理者権限で実行しないとレジストリの一部には書き込めるのに重要なフォルダには書き込めないというような OS が決めたルールがあります。
    
    それに対する対処方法は、もっとも簡単な記述では以下のようになります
    
    ' 管理者として実行を強制する
    Set obj = Wscript.CreateObject("Shell.Application")
    if Wscript.Arguments.Count = 0 then
    	obj.ShellExecute "wscript.exe", WScript.ScriptFullName & " runas", "", "runas", 1
    	Wscript.Quit
    end if
    
    
    
    
    Shell.ShellExecute method
    
    これは、VBScript から利用可能な Shell の機能を使って、右クリックメニューにある『管理者として実行』を実行する方法です。ここでは日本語では無く runas と言う文字列を使って管理者として実行させています。
    
    但し、注意するのは引数なしで実行された場合に、引数をダミーで一つセットして( この場合一つめの runas がそうです )自分自身を再度呼び出して、引数がなかった場合の処理としては処理終了します。
    
    つまり、二度目の実行が管理者としての実行になります。
    
    この場合は、スクリプトに引数を渡す事ができません。もし渡したいしたい場合は、違ったトリックを使う必要があるのに注意して下さい。(その場合は、外部ファイルから入力するのがもっとも簡単で確実だと思います)
    
    
    
    
    
    
    posted by lightbox at 2017-09-01 13:10 | VBS + Shell | このブログの読者になる | 更新情報をチェックする

    他のアプリケーションを『管理者権限』で実行するコマンドライン

    厳密には、テンポラリフォルダに VBScript のコードを作成しますが、バッチ処理でコマンドを実行する時に『管理者権限』を与えたい場合はこれで対処できると思います。
    
    taskmgr は一例です。taskmgr のところに実行したいアプリケーション( exe ) をセットします。
    
    "taskmgr","" の左の文字列は、実行アプリケーションで、右の文字列は引数の文字列を指定します
    
    Shell.ShellExecute method
    
    cmd "/c echo set o=CreateObject("Shell.Application"):o.ShellExecute "taskmgr","","","runas",1 > %TEMP%\_.vbs & wscript.exe %TEMP%\_.vbs"
    
    Windows7 では、taskmgr.exe が管理者権限で実行されると、新しいタスクの作成ダイアログに『このタスクに管理者特権を付与して作成します』チェックボックスが現れます
    
    
    
    
    
    
    
    
    
    
    posted by lightbox at 2017-09-01 13:09 | コマンド : コマンド | このブログの読者になる | 更新情報をチェックする
    container 終わり

    フリーフォントで簡単ロゴ作成
    フリーフォントでボタン素材作成
    フリーフォントで吹き出し画像作成
    フリーフォントではんこ画像作成
    ほぼ自由に利用できるフリーフォント
    フリーフォントの書体見本とサンプル
    画像を大きく見る為のウインドウを開くボタンの作成

    Android SDK ポケットリファレンス
    改訂版 Webデザイナーのための jQuery入門
    今すぐ使えるかんたん ホームページ HTML&CSS入門
    CSS ドロップシャドウの参考デモ
    Google Hosted Libraries
    cdnjs
    BUTTONS (CSS でボタン)
    イラストAC
    ぱくたそ
    写真素材 足成
    フリーフォント一覧
    utf8 文字ツール
    右サイド 終わり
    base 終わり