エントリー

カテゴリー「プログラム」の検索結果は以下のとおりです。

PHP+ImageMagick その2

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

PHP+ImageMagick

特に気にしていなかったけど、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がインストールされていなかったりするらしいので、あまり頼りにはできないのかも。

PHPで自分自身のURLを取得

パスはサーバー変数から取得できるけど、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に貼り付けたとき、段落として認識してもらうためです。

TinyMCE+ThickBoxでファイル挿入

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.thickboxa.insert という値は一例なので、実際のアプリケーションに合わせて適当に変更します。

PHPで添付ファイル付きメールを送信

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でマイムタイプを自動判別

PHPでファイルを読み込んで、そのまま出力するプログラムを書こうとしたのですが、マイムタイプの判別で躓いたのでメモ。

マイムタイプとはデータの形式を指定するためのもので、ブラウザにデータを渡す際に指定する必要があります。
具体的には、GIF画像なら

Content-Type: image/gif

Jpeg画像なら

Content-Type: image/jpeg

テキストなら

Content-Type: text/plain

などです。
今回はどんなファイルでも出力できるようにしたいのですが、マイムタイプは非常にたくさんあるので、上の内容を条件分岐させていくのは面倒です。

拡張子から簡単にマイムタイプを判別する方法は無いものか…と探していたら、以下の関数を発見。

mime_content_type

ファイル名を与えると、image/giftext/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'];

?>

マイムタイプ定義部分が長いので、あとで自分で流用しやすいように全文を置いておきます。関数にして使いまわせるようにするといいかも。突っ込み歓迎。

php_mime.txt

ちなみに、マイムタイプと拡張子は Apache 2.0 の conf/mime.types の内容を参考にしました。連想配列で定義しているだけなので、定義内容の編集は難しくないと思います。

TinyMCEの本文へHTMLを挿入

TinyMCEは高機能なエディタですが、ファイル管理機能がありません。(プラグインとして作成されてはいますがシェアウェアです。)

そこで「freo側で管理しているファイルをTinyMCEの本文へ挿入できれば、ファイル管理のプラグインが無くても大丈夫そう」と思って、本文へ画像タグを挿入する方法を調べたのでメモ。

ちなみに「TinyMCEのツールバーにあるアイコンをクリックすると画像を挿入できる」という方法ではなく、「画面上のボタンやリンクをクリックしたときに画像を挿入できる」という方法です。(前者は、emotionsプラグインとか参考にすれば何とかなりそう。)

以下のコードで、本文に画像タグを挿入できました。

tinyMCE.execCommand(
  'mceInsertContent',
  false,
  '<img src="http://www.example.com/test.jpg" alt="テスト" width="200" height="150" />'
);

これをonclickなどのイベントが実行されたときに呼び出すようにすればOK。上の例は画像タグの挿入ですが、テーブルタグでも定型句でも、何でも挿入できます。

色々な事に応用できそうです。

TinyMCE設定メモ

標準機能にはしないと思いますが、現在このブログにはTinyMCEを導入しています。なので、以下のような画面で記事の入力が可能です。

20090807.png

TinyMCEは設定をいじれば色々できそうですが、解りやすい解説サイトが見当たらないので忘れないうちに自分用にメモ。導入方法の解説ページはたくさんあるんだけど…。

現在の設定

tinyMCE.init({
  language: 'ja',
  mode: 'exact',
  elements: 'tiny_mce',
  entities: '38,amp,60,lt,62,gt',
  content_css: '~CSSファイルへのパス~',
  convert_urls: false,
  dialog_type: 'modal',
  plugins: 'advimage,advlink,autosave,contextmenu,fullscreen,inlinepopups,searchreplace,table',
  theme: 'advanced',
  theme_advanced_blockformats: 'p,pre,h4,h5,h6',
  theme_advanced_buttons1: 'bold,italic,strikethrough,|,bullist,numlist,|,table,|,formatselect,|,visualaid,code,fullscreen,help',
  theme_advanced_buttons2: 'forecolor,backcolor,removeformat,|,link,unlink,image,charmap,|,search,replace,|,undo,redo',
  theme_advanced_buttons3: '',
  theme_advanced_toolbar_location: 'top',
  theme_advanced_toolbar_align: 'left',
  theme_advanced_statusbar_location: 'bottom',
  theme_advanced_resizing: true
});

備考

Enterキーを押したら段落…ではなく、ただの改行を入力したい

force_br_newlines: true,
force_p_newlines: false,

を入力したら &hellip; に変換して記録されるなど、余計な変換をしないように

entities: '38,amp,60,lt,62,gt',

URLを http:// から入力したとき、勝手に相対パスに変換されないように

convert_urls: false,

PHPでディレクトリの内容をリスト表示

自分用にメモ。

ディレクトリの内容をリストですべて表示するプログラム。記事のツリー表示や全文検索やサイトマップ自動作成などに応用できるかもしれません。

<?php

function get_tree($path)
{ 
  if (!is_dir($path)) {
    return;
  }

  $trees = array();

  if ($dir = scandir($path)) {
    foreach ($dir as $entry) {
      if ($entry == '.' or $entry == '..') {
        continue;
      }
      if (is_dir($path . '/' . $entry)) {
        $trees[$entry] = get_tree($path . '/' . $entry);
      } else {
        $trees[$entry] = $path . '/' . $entry;
      }
    }
  }

  return $trees;
}

function put_tree($trees)
{
  if (!is_array($trees)) {
    return;
  }

  echo '<ul>';

  foreach ($trees as $key => $value) {
    if (is_array($value)) { 
      echo '<li>[d] ' . $key;
      put_tree($value);
      echo '</li>';
    } else {
      echo '<li>[f] '.  $key . '</li>';
    }
  }

  echo '</ul>';

  return;
}

$dir   = './sample'; //sampleディレクトリの内容を表示
$trees = get_tree($dir);

?>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=Shift_JIS">
<title>ディレクトリ表示</title>
</head>
<body>
<?php put_tree($trees); ?>
</body>
</html>

実行すると以下のようにリストタグでツリー表示されます。ディレクトリには [d]、ファイルには [f] が表示されます。

<ul>
  <li>[d] sample1
    <ul>
      <li>[d] sample1-1
        <ul>
          <li>[f] sample1-1-1.txt</li>
          <li>[f] sample1-1-2.txt</li>
        </ul>
      </li>
      <li>[f] sample1-1.txt</li>
      <li>[f] sample1-2.txt</li>
    </ul>
  </li>
  <li>[d] sample2
    <ul>
      <li>[f] sample2-1.txt</li>
      <li>[f] sample2-2.txt</li>
    </ul>
  </li>
  <li>[f] test1.txt</li>
  <li>[f] test2.txt</li>
</ul>

ページ移動

ユーティリティ

カテゴリー

検索

エントリー検索フォーム
キーワード

過去ログ

過去ログ表示フォーム
キーワード

Feed