SQLの窓

2024年08月05日


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

fake sendmail は、XAMPP に同梱されています

メールサーバは、フリーメールで可能で、簡単な設定で利用できます。以下のサンプルは、さくらインターネット で動作確認しました。

▼ 手順

ダウンロード

配布元より、sendmail.zip をダウンロードして、解凍します。
( XAMPP には sendmail フォルダがあります )

sendmail.exe の動作テスト

まず、sendmail.ini をエディタで開いて、四つのエントリを指定します
▼ さくらインターネットを使う場合の設定
smtp_server=初期ドメイン
smtp_port=587
auth_username=ユーザ@初期ドメイン
auth_password=パスワード
※ smtp_ssl=auto となっており、デフォルトで ssl で実行され、使え無い場合は TLS を使おうとします php.ini の設定
sendmail_path = "C:\tools\sendmail\sendmail.exe"
実際の sendmail.exe のパスを "" で囲んで指定します。 ※ この場合、エラーログは "C:\tools\sendmail\error.log" です( デフォルト ) PHP のコード ( UTF8 BOM なしで記述します ) HTML の input 要素で type="text" name="fld_to"、name="fld_subject"、name="fld_body"、を form 要素の中に記述し、form 要素に method="post" action="以下の PHP のファイルのパス" を指定し、form 要素の中に input 要素で type="submit" を指定したボタンを記述します。
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 = "OK";
}
else {
	$error = "ERROR";
}

print mb_language() . "
"; print $error;
$GLOBALS["mail"] は、メール形式であれば良いですが、通常ならば auth_username で指定したメールアドレスを記述します。

PHP の mb_send_mail の使用方法の全体のサンプルは、こちらを参照して下さい。





posted by lightbox at 2024-08-05 10:36 | PHP + 通信 | このブログの読者になる | 更新情報をチェックする

2019年01月24日


PHP の cURL でファイルアップロード

cURL を使うとWEBの通信部分の面倒な部分( ssl や ファイルアップロード ) を簡単に処理してくれます。ここで、file-upload.php は、WEB サーバー上ですが、upload.php は、Windows のローカルPC から、コマンドプロンプトで php.exe upload.php で実行可能です

※ 昔と違って、CURLFile クラス を使わないとファイルをアップロードできません

※ MIME 情報は Fileinfo 関数 で取得しています。

関連する記事

VBScript から PHP へファイルアップロード
PHP : cURL で FTP + SSL ダウンロード

file-upload.php
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>ファイルアップロードの簡易テンプレート</title>
</head>
<body>
<form 
	enctype="multipart/form-data"
	method="POST">
 
	アップロードするファイル : 
	<input name="target" type="file">
	<p><input type="submit" value="アップロード"></p>
 
</form>
<pre>
<?php
if ( $_SERVER['REQUEST_METHOD'] == "POST" ) {

	// アップロードするフォルダ
	$upload = realpath ( "./image" );
	// アップロードするファイル
	$upload .= ( "\\" . str_replace( "%", "", urlencode( $_FILES['target']['name'] ) ));
	// 一時ファイルをアップロードファイルとして移動
	if ( move_uploaded_file(
		$_FILES['target']['tmp_name'], $upload ) ) {
		print "アップロードに成功しました<br>\n";
	}

	// アップロード情報の表示
	print_r( $_FILES );

}

?>
</pre>
</body>
</html>


upload.php
<?php
// ***************************************************
// curl 処理
// ***************************************************
$url = "http://localhost/lightbox/20190124/file-upload.php";

$curl = curl_init();
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, $url);

// POST ( デフォルトは GET )
curl_setopt($curl, CURLOPT_POST, true);

// アップロードするファイル
$path = 'lightbox.jpg';

// Windows では extension=php_fileinfo.dll が必要
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $path);
finfo_close($finfo);

// CURLFile クラスのコンストラクタ
// 1) 実際のファイルのパス
// 2) ファイルの MIME
// 3) アップロード先に渡すファイル名
$data = array( 'target' => new CURLFile($path, $mime, 'lightbox-upload.jpg') );
curl_setopt($curl, CURLOPT_POSTFIELDS, $data );

// ***************************************************
// デバッグ用
// ***************************************************
curl_setopt($curl, CURLOPT_VERBOSE, true);	

$handle1 = fopen("./debug.txt", "w");
curl_setopt($curl, CURLOPT_STDERR, $handle1);

$handle2 = fopen("./ret_header.txt", "w");
curl_setopt($curl, CURLOPT_WRITEHEADER, $handle2);

// ***************************************************
// SSL
// ***************************************************
if ( substr( $url, 0, 5 ) == "https" ) {
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true);
}

// ***************************************************
// 送信
// ***************************************************
$result = curl_exec($curl);

// ***************************************************
// 結果
// ***************************************************
if($result === false) {
	$result = 'Curl error: ' . curl_error($curl);
}
curl_close($curl);
fclose($handle2);
fclose($handle1);

print( $result . "\n" );

?>





タグ:Curl
posted by lightbox at 2019-01-24 16:34 | PHP + 通信 | このブログの読者になる | 更新情報をチェックする

2019年01月21日


PHP : WEB でもコマンドラインでも HTTP でファイルをダウンロードする 『fget.php』

fopen wrappers が有効の場合、WEB 上で配置するとそのサーバー以外の別のサーバにあるファイルを http 経由でいったん読み込んでからクライアントへ送ります。その際、ファイルサイズが必要になるので、readfile に先立って、cURL で、ファイルサイズだけを取得しています。

readfile はこのような処理に使う為の関数ですが、標準出力へ内容を出力するのでコマンドプロンプトで使う場合はファイルへリダイレクトする必要があります。なので、ここではコマンドプロンプトの場合は readfile を使用せずに通常のファイル処理としてファイルを書き込んでいます。

fget.php
<?php
// **************************************************
// 【fget.php】
// http:// で他のサーバのファイルを読み込んでダウンロードします
// 【利用方法】
// WEB : fget.php?target=URLエンコードされたURL&name=保存ファイル名
// CMD : 1) php.exe fget.php URL
// CMD : 2) php.exe fget.php URL 保存ファイル名
// **************************************************

// **************************************************
// コマンドラインでも使えるように
// **************************************************
if (substr(php_sapi_name(), 0, 3) == 'cgi') {
	$remoteFile = $_GET['target'];
}
else {
	$remoteFile = $argv[1];
}

// 保存ファイル名をパスから作成
$fileName = basename($remoteFile);

// 保存ファイル名を指定した場合
if (substr(php_sapi_name(), 0, 3) == 'cgi') {
	// WEBアプリで 保存ファイル名を指定
	if ( isset($_GET['name']) ) {
		$fileName = $_GET['name'];
	}
}
else {
	// コマンドプロンプトで 保存ファイル名を指定
	if ( isset($argv[2]) ) {
		$fileName = $argv[2];
	}
}

// **************************************************
// PHP オンラインマニュアルの投稿データより
// ファイルのサイズを取得する cURL の処理
// **************************************************
$ch = curl_init($remoteFile);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
if ( substr( $remoteFile, 0, 5 ) == "https" ) {
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
}
$data = curl_exec($ch);
curl_close($ch);
if ($data === false) {
	echo 'cURL failed';
	exit;
}

$contentLength = 'unknown';
$status = 'unknown';
if (preg_match('/^HTTP\/1\.[01] (\d\d\d)/', $data, $matches)) {
	$status = (int)$matches[1];
}
if (preg_match('/Content-Length: (\d+)/', $data, $matches)) {
	$contentLength = (int)$matches[1];
}

// **************************************************
// WEB 経由ダウンロード
// **************************************************
if (substr(php_sapi_name(), 0, 3) == 'cgi') {
	header( "Content-Type: application/octet-stream" );
	header( "Content-disposition: attachment; filename={$fileName}" );

	$path = $remoteFile;

	header( "Content-Length: $contentLength" );

	readfile($path);

	exit();
}
// **************************************************
// Windows コマンドライン
// Windows では、fopen()の mode パラメータに 'b' を
// 指定してファイルをオープンする必要があります。
// **************************************************
else {
	$ihandle = fopen($remoteFile, "rb");
	$ohandle = fopen($fileName, "wb");
	if ( $ihandle ) {

		while( !feof($ihandle) ) {
			$ret = fread( $ihandle, 1024 );
			fwrite( $ohandle,  $ret );
		}

		fclose( $ohandle );
		fclose( $ihandle );
	}

	exit();
}

?>


関連する情報

PHP fread

fread の第二引数は、読み込む最大バイトなので、EOF に達すると、それ以内のデータが取得されます。

PHP fwrite

大きなファイルですと、問題が出るという報告もあるので、その場合は以下のように readfile を書き換えるといいかもしれません。

Streaming a large file using PHP

Problem with download of larger files





posted by lightbox at 2019-01-21 16:12 | PHP + 通信 | このブログの読者になる | 更新情報をチェックする

PHP : cURL : Google Photo API の albums.list メソッドを使用して アルバム一覧データを取得する

Google Photo API を使用するには、認証されたアクセストークンが必要です。なので、ここで使用しているアクセストークンは、別のコードで取得したものをセッションに保存して利用しています。

$_SESSION['access_token']

アクセストークンは 3600 秒しか使用できないので随時必要な時に新たに取得する必要があります。( refresh_token を取得して使用します。その場合最初の認証の URL に access_type=offline をセットして認証する必要があります / ※ 認証時にしか取得できませんでした )

$_SESSION['access_token'] は、PHP + cURL で Google Photo API の アクセストークンを取得する のコードに session_start(); を先頭に追加してセッションを使用可能にしてから、以下のコードを最後に使用して保存します。
$token = json_decode($result, true);

print "<pre>";
print_r($token);
print "</pre>";

$_SESSION['access_token'] = $token['access_token'];

// ************************************
// refresh_token は、認証の URL に 
// access_type=offline を使用して
// 認証した最初のみ取得できるようです
// ************************************
if ( !isset( $_SESSION['refresh_token'] ) ) {
	$_SESSION['refresh_token'] = $token['refresh_token'];
}


album-list.php
<?php
session_cache_limiter('nocache');
session_start();

?>
<!DOCTYPE html>
<html>
<head>
<meta content="width=device-width initial-scale=1.0 minimum-scale=1.0 maximum-scale=1.0 user-scalable=no" name="viewport">
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
</head>
<body>
<?php

print "<pre>";
print_r($_SESSION);
print "</pre>";

$start = true;
$page_token = '';

// ************************************
// curl 処理
// ************************************
$curl = curl_init();

// ************************************
// デバッグ用の詳しいメッセージを出力
// ************************************
curl_setopt($curl, CURLOPT_VERBOSE, true);
$fp_debug = fopen("./debug.txt","w");
curl_setopt($curl, CURLOPT_STDERR, $fp_debug);

// ************************************
// HTTP ヘッダ
// ************************************
$header[] = "Authorization: Bearer {$_SESSION['access_token']}";
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);

// ************************************
// オプション
// ************************************
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

// ************************************
// https 用
// ************************************
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true);

// ************************************
// ヘッダ内容
// ************************************
$handle = fopen("./header.txt", "w");
curl_setopt($curl, CURLOPT_WRITEHEADER, $handle);
 
// ************************************
// アルバムを全て取得
// access_albums( ) が true を返す間
// ループする
// ************************************
while( access_albums( ) ) { }

// ************************************
// 終了処理
// ************************************
curl_close($curl);
fclose($fp_debug);
fclose($handle);

// ************************************
// アルバムを全て取得する関数
// ************************************
function access_albums( ) {

	// 開始フラグ
	global $start;

	// 最大50件の読み込みでまだアルバムがある場合に
	// セットされるデータ
	global $page_token;

	// cURL ハンドル
	global $curl;

	// 初回
	if ( $start ) {
		$start = false;
		$url = "https://photoslibrary.googleapis.com/v1/albums?pageSize=50";
	}
	// 2回目以降
	else {
		$url = "https://photoslibrary.googleapis.com/v1/albums?pageSize=50&pageToken={$page_token}";
	}

	// URL を設定( v1/albums は GET メソッド )
	curl_setopt($curl, CURLOPT_URL, $url );
	// ************************************
	// 送信
	// ************************************
	$result = curl_exec($curl);
	if($result === false) {
		// cURL そのものがエラー
		return false;
	}
	else {
		// 正しいデータを取得したので連想配列に変換
		$json = json_decode( $result, true );

		// 出力
		print "<pre>";
		print_r( $json );
		print "</pre>";

		// この呼び出しで全ての場合は false を返して終了
		if ( !isset( $json['nextPageToken'] )) {
			return false;
		}
	}

	// 次の一覧を取得する為のデータ
	$page_token = $json['nextPageToken'];

	// 次を読む
	return true;

}

?>
</body>
</html>





posted by lightbox at 2019-01-21 15:05 | PHP + 通信 | このブログの読者になる | 更新情報をチェックする

2019年01月20日


PHP + cURL で Google Photo API の アクセストークンを取得する

Google API ConsoleWebアプリケーションの OAuth クライアント ID を取得して使用します。そこには、承認済みのリダイレクト URI を登録して API からの呼び出しでその URI を呼べるようにします。

そうすると、以下の URL で Google API の oauth によりアカウントで権限の承認を行った後準備しておいた リダイレクト URI  にジャンプします。

その時 code が手に入るので、それと認証情報の他のデータを使って cURL で アクセストークンを取得します( アクセストークンの生存期間は3600秒 )

クライアント ID : 
登録した承認済みのリダイレクトURI : 



https://accounts.google.com/o/oauth2/v2/auth?client_id=クライアントID&response_type=code&scope=https://www.googleapis.com/auth/photoslibrary&redirect_uri=登録した承認済みのリダイレクトURI

承認済みのリダイレクト URI に用意する PHP
<?php

// ************************************
// 表示用
// ************************************
print "<pre>";
print_r($_GET);

// ************************************
// API データ
// ************************************
$client_id = 'クライアント ID';
$client_secret = 'クライアント シークレット';
$redirect_uri = 'http://localhost/gapi/examples/idtoken.php';

// ************************************
// curl 処理
// ************************************
$curl = curl_init();

// ************************************
// デバッグ用の詳しいメッセージを出力
// ************************************
curl_setopt($curl, CURLOPT_VERBOSE, true);
$fp_debug = fopen("./debug.txt","w");
curl_setopt($curl, CURLOPT_STDERR, $fp_debug);

// ************************************
// POST 処理
// ************************************
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_URL, "https://www.googleapis.com/oauth2/v4/token");
// ************************************
// データ
// ************************************
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query([
	'code' => $_GET['code'],
	'client_id' => $client_id,
	'client_secret' => $client_secret,
	'redirect_uri' => $redirect_uri,
	'grant_type' => 'authorization_code'
]));

// ************************************
// オプション
// ************************************
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

// ************************************
// https 用
// ************************************
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true);

// ************************************
// ヘッダ内容
// ************************************
$handle = fopen("./header.txt", "w");
curl_setopt($curl, CURLOPT_WRITEHEADER, $handle);
 
// ************************************
// 送信
// ************************************
$result = curl_exec($curl);
if($result === false) {
	$result = 'Curl error: ' . curl_error($ch);
} 

// ************************************
// 終了処理
// ************************************
curl_close($curl);
fclose($fp_debug);
fclose($handle);
 
// ************************************
// 結果
// ************************************
print $result;

// ************************************
// 表示用
// ************************************
print "</pre>";

?>


関連する記事

Windows 用 curl で、Googls Photo API を呼び出して画像の baseUrl を取得する




posted by lightbox at 2019-01-20 20:39 | PHP + 通信 | このブログの読者になる | 更新情報をチェックする

PHP : cURL で FTP + SSL ダウンロード

サンプルは、PHP のオンラインマニュアルの投稿部分にあります。この、「投稿部分」には昔から結構重要な情報が掲載されています。特に、SSL についてはマニュアル本文に無いパラメータがあり、libcurl.a の Cドキュメントからの参照が記述されています。(実際、本文のパラメータだけは SSL にはなりませんでした)

以下は、コマンドプロンプトからの実行を想定していますので、実行は以下のようになります。
php.exe ftp_ssl_download.php

また、Windows では、php.ini で extension=php_curl.dll が必要です。実際、SSL が使われたかどうかの確認は、debug.txt を参照して確認できます。

ftp_ssl_download.php

<?php
// ************************************
// ユーザとパスワード
// ************************************
$username = 'ユーザ';
$password = 'パスワード';

// ************************************
// 対象ファイル
// ログインディレクトリからの相対位置
// ************************************
$url = 'ドメイン/www/homepage/download/WinOfSql102.zip';

// ************************************
// URL
// ************************************
$ftp_server = "ftp://" . $username . ":" . $password . "@" . $url;

// ************************************
// 開始
// ************************************
$ch = curl_init();

// ************************************
// デバッグ用の詳しいメッセージを出力
// ************************************
curl_setopt($ch, CURLOPT_VERBOSE, true); 
$fpe = fopen("./debug.txt","w");
curl_setopt($ch, CURLOPT_STDERR, $fpe);

// ************************************
// 転送用のオプション
// ************************************
curl_setopt($ch, CURLOPT_URL, $ftp_server);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

// ************************************
// SSL である事の明示
// ※ CURLFTPSSL_ALL と CURLFTPSSL_TRY があります
// ************************************
curl_setopt($ch, CURLOPT_FTP_SSL, CURLFTPSSL_ALL);

// ************************************
// ダウンロードされるファイル
// ************************************
$fp = fopen("./target.zip","w");
curl_setopt($ch, CURLOPT_FILE, $fp);

// ************************************
// 実行
// ************************************
$result = curl_exec($ch);
if($result === false) {
	$result = 'Curl error: ' . curl_error($ch);
}

// ************************************
// 終了
// ************************************
curl_close($ch);

// ************************************
// 後処理
// ************************************
fclose($fp);
fclose($fpe);

print $result . "\n";
?>
OK





タグ:PHP Curl 通信
posted by lightbox at 2019-01-20 00:01 | PHP + 通信 | このブログの読者になる | 更新情報をチェックする
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。

Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。

また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。

※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです

対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。


※ エキスパートモードで表示しています

アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります

<% if:page_name eq 'archive' -%>
アーカイブページでのみ表示される内容
<% /if %>

<% if:page_name eq 'category' -%>
カテゴリページでのみ表示される内容
<% /if %>

<% if:page_name eq 'tag' -%>
タグページでのみ表示される内容
<% /if %>
この記述は、以下の場所で使用します
container 終わり



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

CSS ドロップシャドウの参考デモ
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり