携帯対応
ひととおりの機能を携帯対応にしたのでテスト。ファイルアップロード以外は、パソコン経由と同じ機能が利用できます。
もう少しテストしてから配布予定。
気ままな雑記帳&実験場。好き勝手に色々やっています。
カテゴリー「制作」の検索結果は以下のとおりです。
ひととおりの機能を携帯対応にしたのでテスト。ファイルアップロード以外は、パソコン経由と同じ機能が利用できます。
もう少しテストしてから配布予定。
今年はC#を勉強しよう!…というわけで、ひとまず開発環境をインストールしてみた。
C#は、高機能な開発環境がMicrosoftから無償で提供されています。色んなソフトを別々に入手して設定して…が不要なので、インストール作業はとても簡単。
解説は、ひとまず以下の2つを読んでいこうと思います。
しばらくはコンソールで実行するプログラムばかりの制作になりますが、目標はWindowsアプリケーションの制作。
ざっと読んだ限りでは「C言語 + Windows API を直接呼出し」に比べれば圧倒的に簡単っぽいので、何とかなるかなぁ…。
さらにImageMagickについて。
ImageMagickの実行には exec()
関数を使っていたけど、shell_exec()
の方が個人的には読みやすいので変更。
<?php
echo shell_exec('/usr/bin/convert -version');
?>
ロリポップでImageMagickを使えなかったのは、PHPの設定で safe_mode
を On
にしていたからでした。すっかり忘れてた…。(正確には、ImageMagickではなく exec()
や shell_exec()
の実行に制限がかかります。)Off
にすれば無事実行できました。一安心。
また、ImageMagickは処理結果は常にファイルに出力されるのかと思っていたけど、標準出力に渡すこともできるのですね。
以下のようにすれば、150px×150pxのサムネイルを直接画面に表示できます。
<?php
echo shell_exec('/usr/bin/convert -geometry 150x150 illust.png -');
?>
さらに、以下のようにすればJpegに変換した上で直接画面に表示できます。
<?php
echo shell_exec('/usr/bin/convert -geometry 150x150 illust.png jpg:-');
?>
freoで使いそうなのはサムネイル作成と画像形式変換くらいなので、これで実装できそうです。
freoに実装するためにImageMagickの使い方を調べてみたのでメモ。…と思ったけど、メモするほどでもないかも。(^^;
色々な処理がとても簡単にできて素敵です。
バージョン情報を表示
/usr/bin/convert -version
PNGをGifに変換
/usr/bin/convert illust.png illust.gif
PNGをJpegに変換
/usr/bin/convert illust.png illust.jpg
150px×150pxのサムネイルを作成
/usr/bin/convert -geometry 150x150 illust.png thumbnail.png
画質70を指定して150px×150pxのサムネイルを作成
/usr/bin/convert -geometry 150x150 -quality 70 illust.png thumbnail.jpg
特に気にしていなかったけど、GDよりもImageMagickの方が綺麗な画像が作れるらしいので、PHPからImageMagickを呼び出す方法を調べてみた。
PHPではPECLのImagickクラスでImageMagickを扱えるみたいだけど、利用できるサーバーは少ないようなので、直接ImageMagickを呼び出す方法にしてみます。
<?php
exec('/usr/bin/convert -version', $output);
print_r($output);
?>
とりあえずバージョン情報を表示するだけのプログラム。ImageMagickが使えるサーバーなら
Array
(
[0] => Version: ImageMagick 6.0.7 04/20/08 Q16 http://www.imagemagick.org
[1] => Copyright: Copyright (C) 1999-2004 ImageMagick Studio LLC
[2] =>
)
とか表示されます。…が、ロリポップサーバーでは何も表示されませんでした…。
マニュアルを読むとImage::Magickは利用可らしいけど、PHPからはダメとかあるのかなぁ…。
色々調べてみると、ロリポップはサーバーによってはImage::Magickがインストールされていなかったりするらしいので、あまり頼りにはできないのかも。
パスはサーバー変数から取得できるけど、URLは取得できるのか調べてみた。
どうやら以下のコードで大丈夫っぽい。
<?php
echo 'http://' . $_SERVER["SERVER_NAME"] . $_SERVER["SCRIPT_NAME"];
?>
freoアルファ版の小説管理サンプルとして、青空文庫の小説を使用する予定。青空文庫では、著作権切れの文学作品を読むことができます。
ただ、「できればルビなしのデータがほしいなぁ…。」と思ったのですが、配布されているのはルビありのデータのみのようです。
そんな訳で、テキスト形式で配布されているデータから、ルビを削除するプログラムをPerl(CGIではない)で書いてみた。
my $org_file = 'org.txt';
my $new_file = 'new.txt';
my $new = '';
if (open(FH, $org_file)) {
while ($data = <FH>) {
$data =~ s/《[^》]+》//g;
$data =~ s/|//g;
$data =~ s/(\r|\n)//g;
$new .= $data . "\n\n";
}
close(FH);
}
if (open(FH, '>' . $new_file)) {
print FH $new;
close(FH);
}
exit;
ルビを削除するついでに各行の最後に改行を1つ追加していますが、TinyMCEに貼り付けたとき、段落として認識してもらうためです。
ThickBoxで作ったiframe内部から、TinyMCEの本文へデータを挿入する仕組みでハマったのでメモ。iframe内で色々操作すると、IEではTinyMCEのカーソル位置がリセットされてしまうことがあります。つまり、意図した位置にデータが挿入されないことがあります。
IEの場合はどうにもならないのかなぁ…と思ったけど、WordPressにあるファイル挿入機能ではカーソル位置を正しく記憶しているので、WordPressではどうやって処理しているのかコードを調べてみた。
大量のコードから該当箇所を突き止めるのに時間がかかったけど、どうやらIEの場合のみ、カーソル位置を別途保持しておく必要があるみたい。
↓ThickBoxオープン時にカーソル位置を記憶。
$(document).ready(function() {
$('a.thickbox').click(function() {
if (tinymce.isIE) {
tinyMCE.get('tiny_mce').focus();
tinyMCE.activeEditor.windowManager.bookmark = tinyMCE.activeEditor.selection.getBookmark();
}
});
});
↓データ挿入時にカーソル位置を復元。
$(document).ready(function() {
$('a.insert').click(function() {
if (parent.tinymce.isIE) {
parent.tinyMCE.activeEditor.focus();
parent.tinyMCE.activeEditor.selection.moveToBookmark(parent.tinymce.EditorManager.activeEditor.windowManager.bookmark);
}
parent.tinyMCE.activeEditor.execCommand('mceInsertContent', false, '挿入したいデータ');
parent.tb_remove();
});
});
a.thickbox
や a.insert
という値は一例なので、実際のアプリケーションに合わせて適当に変更します。
PHPには mb_send_mail()
という命令があり、これを使うと簡単に日本語メールを送信することができます。ただし添付ファイルには対応していないので、添付ファイルを扱う場合は利用できません。
大抵の解説では「mail()
関数を使ってメールヘッダを自力で書けば添付ファイルも送れますが、面倒なのでPEARなどを使いましょう。」とか書かれています。ですが例によってPEARは使いたくないので、自力でヘッダなどを書いてみた。
<?php
//マイムタイプ定義
$mime_content_types = array(
'ez' => 'application/andrew-inset',
'atom' => 'application/atom+xml',
'atomcat' => 'application/atomcat+xml',
~略~
'avi' => 'video/x-msvideo',
'movie' => 'video/x-sgi-movie',
'ice' => 'x-conference/x-cooltalk'
);
//送信先メールアドレス
$to = 'example@example.com';
//送信元メールアドレス
$from = 'example@example.com';
//件名
$subject = '添付ファイルのテスト';
//メール本文
$message = "テストメール。\n";
$message .= "添付ファイル送信のテストです。\n";
//添付ファイル
$files = array('images/test.gif');
//件名・本文をエンコード
$subject = mb_convert_encoding($subject, 'JIS', 'UTF-8');
$message = mb_convert_encoding($message, 'JIS', 'UTF-8');
$subject = '=?iso-2022-jp?B?' . base64_encode($subject) . '?=';
//バウンダリ文字列を定義
if (empty($files)) {
$boundary = null;
} else {
$boundary = md5(uniqid(rand(), true));
}
//メールボディを定義
if (empty($files)) {
$body = $message;
} else {
$body = "--$boundary\n";
$body .= "Content-Type: text/plain; charset=\"iso-2022-jp\"\n";
$body .= "Content-Transfer-Encoding: 7bit\n";
$body .= "\n";
$body .= "$message\n";
foreach($files as $file) {
if (!file_exists($file)) {
continue;
}
$info = pathinfo($file);
$content = $mime_content_types[$info['extension']];
$filename = basename($file);
$body .= "\n";
$body .= "--$boundary\n";
$body .= "Content-Type: $content; name=\"$filename\"\n";
$body .= "Content-Disposition: attachment; filename=\"$filename\"\n";
$body .= "Content-Transfer-Encoding: base64\n";
$body .= "\n";
$body .= chunk_split(base64_encode(file_get_contents($file))) . "\n";
}
$body .= '--' . $boundary . '--';
}
//メールヘッダを定義
$header = "X-Mailer: PHP5\n";
$header .= "From: $from\n";
$header .= "MIME-Version: 1.0\n";
if (empty($files)) {
$header .= "Content-Type: text/plain; charset=\"iso-2022-jp\"\n";
} else {
$header .= "Content-Type: multipart/mixed; boundary=\"$boundary\"\n";
}
$header .= "Content-Transfer-Encoding: 7bit";
//メール送信
if (mail($to, $subject, $body, $header)) {
echo 'メールが送信されました。';
} else {
echo 'メールの送信に失敗しました。';
}
?>
プログラムはUTF-8で書くことを前提としています。
$mime_content_types
の定義内容の全文はPHPでマイムタイプを自動判別に記載しています。添付ファイルのマイムタイプは常に application/octet-stream
でも大丈夫っぽいですが、正しく定義した方が好ましいようです。
添付ファイルは $files
に配列の形式でいくつでも設定できます。添付ファイルが無い場合、それにあわせてメールヘッダなどの内容も自動で変化します。
特に問題なく送信できましたが、書いたばかりなので近々じっくりテストしてみます。
PHPでファイルを読み込んで、そのまま出力するプログラムを書こうとしたのですが、マイムタイプの判別で躓いたのでメモ。
マイムタイプとはデータの形式を指定するためのもので、ブラウザにデータを渡す際に指定する必要があります。
具体的には、GIF画像なら
Content-Type: image/gif
Jpeg画像なら
Content-Type: image/jpeg
テキストなら
Content-Type: text/plain
などです。
今回はどんなファイルでも出力できるようにしたいのですが、マイムタイプは非常にたくさんあるので、上の内容を条件分岐させていくのは面倒です。
拡張子から簡単にマイムタイプを判別する方法は無いものか…と探していたら、以下の関数を発見。
ファイル名を与えると、image/gif
や text/plain
という値を返してくれるそうです。これは便利!と思ったら、この関数の利用は非推奨だそうです。実際、環境によっては利用できません…。
代わりにPECL拡張モジュールを使うといいらしいですが、やっぱり利用できない環境があります。PEARを使って判別することもできるらしいですが、できればPEARは使いたくないです。(freoではPEARを一切使わない方針なので。)
…という訳で、いい方法を見つけられなかったので「拡張子からマイムタイプを自動判別する」処理を自作してみた。結局ものすごく露骨な処理になりましたが、あらかじめ拡張子とマイムタイプを定義しておくだけです。
<?php
//マイムタイプ定義
$mime_content_types = array(
'ez' => 'application/andrew-inset',
'atom' => 'application/atom+xml',
'atomcat' => 'application/atomcat+xml',
~略~
'avi' => 'video/x-msvideo',
'movie' => 'video/x-sgi-movie',
'ice' => 'x-conference/x-cooltalk'
);
//GIF画像ファイルのマイムタイプを出力
echo $mime_content_types['gif'];
//テキストファイルのマイムタイプを出力
echo $mime_content_types['txt'];
?>
マイムタイプ定義部分が長いので、あとで自分で流用しやすいように全文を置いておきます。関数にして使いまわせるようにするといいかも。突っ込み歓迎。
ちなみに、マイムタイプと拡張子は Apache 2.0 の conf/mime.types
の内容を参考にしました。連想配列で定義しているだけなので、定義内容の編集は難しくないと思います。