タグ「PHP」が付けられているもの

パソコン、スマホ、タブレットなど、どの端末からでもメールを確認できるWEBメーラー。いろいろありますが、やっとレンタルサーバーで使える理想の物を見つけましたRainLoop Webmail

自前のLinuxサーバーに入れてみたというようなブログはたくんさんヒットしたのですが、レンタルサーバーに入れてみた記事は見当たらず、入れてみたらどうなるのかな~と、現在使用しているバリューサーバー(ValueServer)でも使えたのでメモ。

  • PHP製で無料
  • レンタルサーバーでも動く
  • 設定・設置が簡単
  • DBはSQLiteで設定不要(MySQL、PostgreSQLも使える)
  • 日本語対応
  • リッチなユーザーインターフェース
  • デザインがよくテーマも変更できる
  • スマホやタブレット用のレイアウトあり
  • メールアドレスの切り替えが簡単

パソコンの画面

スマホの画面

デモサイト

こちら↓のデモサイトでデザインの確認と試用ができます。

設置してみる

設置はとても簡単です。ダウンロードしたファイルをアップロードするだけです。データベースはSQLiteがデフォルトで特に設定するものはなく、CMSみたいにデータベースの設定やConfigファイルを事前に準備する作業はありませんでした。

ダウンロード

Downloadページから「Community edition」をダウンロードする。Standard editionというのもありますが、Community editionをダウンロードします。(今日現在のバージョンはv1.10.5.192)

解凍する

ダウンロードした「rainloop-community-latest.zip」を解凍します。

サーバーにアップロード

WEBサーバーにRainLoop用のフォルダをルートでもどこでもいいので、rainloopとかwebmailとか適当にフォルダを作成し、そこに解凍したフォルダの中にある以下の3つをアップロードします。

  • data
  • rainloop
  • index.php

パーミッションを設定

  • フォルダ:755
  • ファイル:644

以上で、設置は完了です。

ログインしてみる

この手の物は足りない物があったりして一発で表示されないことがあったりするのですが、あっさりログイン画面が表示されました。まずは管理画面で設定をします。

管理画面にログイン

http://www.example.com/webmail/?adminのようにアップロードしたindex.phpに対して?adminを付けてアクセス。

初期は以下のユーザーIDとパスワードでログインします。

  • 初期ユーザーID:admin
  • 初期パスワード:12345

?adminが無いと管理画面ではなく、見た目が同じのメーラーのログイン画面が表示されログインできません。

言語を日本語に変更

Englishをクリックして2つとも日本語に変更します。

  ↓

管理者のユーザー名とパスワードを変更

「変更」をクリックするか「セキュリティ」の画面で、新しい管理者のユーザー名とパスワードに変更します。変更すると初期の「admin」と「12345」では入れなくなります。

  ↓

メールサーバーの登録

画面左のメニューにある「ドメイン」をクリックして使用するメールのドメインとメールサーバーの情報を登録します。例えば、メールアドレスが[email protected]の場合、example.comを登録します。

  ↓

扱える受信サーバーPOPではなくIMAPのみです。ここはメールサーバーの登録でメールアドレスの設定ではありません。RainLoopにはメールアドレスの情報を設定するところは無いようです。

  ↓

必要な情報を入力して左下の「接続テスト」をクリックすると、正常に接続できた場合、ボタンと文字が緑色になります。そして「追加」を押して追加を完了します。

メールサーバーがIMAPに対応していればGmailやOutlook.comなどのメーラーとしても使えます。登録がデフォルトであるので、使用する場合はチェックをONにします。今回はexample.comだけチェックをONにします。

メールサーバーの設定を編集(変更・修正)する場合はドメイン名をクリックすると上記のメールサーバーの設定画面が表示されます。

  ↓

迷惑メールフィルタを使用する場合

自分で立てたLinuxサーバーのメールサーバーやレンタルサーバーのIMAPサーバーでmanagesieveの機能が有効になっていれば、SEIVEの迷惑メールフィルタの設定もできるようです。

ちなみにバリューサーバー(ValueServer)には入っておらず、設定を入力して「接続テスト」をクリックしたところ赤文字になってエラーになりました。ポートはほとんどの場合20004190のようですが、どちらを入力してもダメでした。

バリューサーバー(ValueServer)ではSpamAssassinでスパム判定し、procmailで迷惑メールを振り分けていてSEIVEは使用できないようです。

以上で、RainLoopの設置と設定は完了です。

ここで「あれ?メールアドレスの設定は?」と思うかもしれませんが、いくら探してもメールアカウントを指定するページはありません。でもメールBOXは開けるの心配ありません。

メールを開いてみる

ログイン

トップページ(http://www.example.com/webmail/)にアクセスし、メールサーバーに登録してあるアカウント名とパスワードでログインします。

メールサーバーによってはアカウント名はメールアドレスではなく、@マークより前の「a」のみだったりして異なる場合があります。

先ほども記載した通り、RainLoopではメールアカウントを設定するところはなく、ログイン画面のメールアカウントとパスワードを管理画面で設定したメールサーバーに送信してメールボックスを開きます。

別のアカウントに切り替え

同じドメインのメールが他にある場合、「アカウントの追加」で追加すると、a@example.comでログインしてb@example.com、c@example.comを右上のメニューから再ログインなしでメールボックスの表示を切り替えることができて便利です。

  ↓

テーマ

テーマはデフォルトでいろいろあって、どれも感じがいいです。メーラーと管理画面で異なるテーマを設定できるようです。

themeフォルダをいじればオリジナルのテーマに着せ替えることもできそうです。

使用しているレンタルサーバーのバージョンが上がったせいか、今まで正常に動いていたPHPのスクリプトでエラーが出始めた。

エラーの内容

なにやらデフォルトのタイムゾーンを設定しろ的なdate_default_timezone_set()に関するエラー。

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /public_html/hoshiya.biz/lib/***.php on line 123

対処法方法

タイムゾーンの設定はphp.iniか.htaccessでするか、スクリプト内に宣言するかなどできます。

php.iniの場合

[Date]セクション内を編集

;date.timezone =
     ↓↓↓
date.timezone = Asia/Tokyo

※スクリプト全てに対して適用されます

.htaccessの場合

以下を追加

php_value date.timezone Asia/Tokyo

※.htaccess制御範囲内のスクリプト全てに対して適用されます

スクリプト内で宣言する場合

date_default_timezone_set('Asia/Tokyo');

※記述を追加したスクリプトのみに対して適用されます

PHPで現在の日付が期限を過ぎていなければ表示しないさいといった判別をするため、わかりやすく2099年12月31日を期限としてみたところ、計算できませんでした。strtotime(date("2099/12/31"))では値を取得できないようです。

<?php
if (strtotime(date("Y/m/d")) <= strtotime(date("2099/12/31"))){
	echo "期限内です。\n";
}else{
	echo "期限を過ぎています。\n";
}
?>

値が取得できていないので期限内なのに"期限を過ぎています。"と表示されました。では、いつまでなら大丈夫なのかといろいろやってみたところ2038/01/19までなら値が判別できました。

<?php
if (strtotime(date("Y/m/d")) <= strtotime(date("2038/01/19"))){
	echo "期限内です。\n";
}else{
	echo "期限を過ぎています。\n";
}
?>

なぜこんなことになっているのか検索してみたところ以下のページが参考になりました。

これによると32ビット環境のPHPで使える有効なタイムスタンプは1901年12月13日 20:45:54から2038年01月19日 03:14:07までだそうです。

今回の判別は時間は関係なく日付だけで行うので、以下のようにstrtotimeで日付を数値にせず日付のまま判別するようにしました。これは2099年でも大丈夫なようです。

<?php
if (date("Y/m/d") <= date("2099/12/31")){
	echo "期限内です。\n";
}else{
	echo "期限を過ぎています。\n";
}
?>

何気なく会社のホームページを見ていたら以下のエラーが出るページに気づきました。

 Warning:number_format() expects parameter 1 to be double, object given in /home/hoge/foo/bar.php on line 99

ここ数か月は特に更新をしていないページなのになんでだろう?と思っていたところ、そういえばレンタルサーバー会社からPHP5.2を終了し、5.3にバージョンアップするといったメールが届いていたの思い出しました。

number_format()のエラーを検索したらあっさり対処法が見つかりました。

$chinryo = number_format($alldata->data[$i]->chinryo);

(int)を加えて

$chinryo = number_format((int)$alldata->data[$i]->chinryo);

とするだけでエラーが出なくなりました。

以下のサイトURLのページによると、エラーの原因はPHP5.3からnumber_formatを含むあらゆる関数に対して互換性のない値が渡されるとNULLを返すのが原因のようです。

ダウンロードしてきたPHPのソースをサーバーに置いてワクワクしながらブラウザでいざ表示ってときにほとんどのケースで「Notice: Undefined variable~」というエラー表示になります(T_T)

原因は変数が定義されていないから

初期値は空だからと思って定義しなかったら、PHPは使用する変数にNULLでもいいから情報を予め入れておかないとエラーとなります。

$foo = "";
$foo = null;
$foo = isset($_GET["foo"]) ? $_GET["foo"] : NULL;

沢山の変数にいちいちNULLや""を定義するのは面倒なので、なにか簡単にエラー回避して解決できないかと検索したら、ありました。

  • 変数に@を付ける
    echo @$foo;
  • php.iniでerror_reportingを設定しておく
    error_reporting = E_ALL & ~E_NOTICE
  • スクリプト内でerror_reporting関数でエラーを制御する
    error_reporting(E_ALL ^ E_NOTICE);

参考サイト

自分の環境の場合、Apaatchのレンタルサーバーではエラーが出ないのに、ローカルのIISだと出たりするなど、WEBサーバーが違うからかな?と思うこともありましたが、あんまり関係がなく、エラー処理が丁寧に行われていないスクリプトだと、500エラーが出たりして正常に動きませんでしたが、上記の対策で解決できました。

社内用のウェブ(イントラネット)にグループウェアを入れたいと考えていたのですが、以下の条件にあうものになかなか巡り会えなくて悩んでいました。

  • 無料である。
  • PHPで動くオープンソース。
  • アドレス帳が備わっている。
  • ファイル共有ができる。

 

こんなもんある訳がないと思い、WordPressやMovableTypeでアドレス帳やファイル共有ができるプラグインがあれば、ある方のCMSで構築するかと考えていましたが、これも見当たらず...。

静的HTMLで作るか...と諦めていましたが、理想に近いものが見つかりました!

 

まだ試していないので、何ともいえませんが、CSSフレームワークや必要なページやメニューを埋め込めばかなりいけそうな気がします。

データベースはMySQLとSQLiteに対応しているそうです。

フォームに入力された内容をPHPのmb_send_mailでメールの送信をしようと、以下のようなスクリプトで送信したらmb_encode_mimeheaderで指定した文字が文字化けしました。

<?php
mb_language("Ja") ;
$to = mb_encode_mimeheader("A様","iso-2022-jp")."<a@aaa.com>";
$subject = "◯◯の件について";
$subject = mb_convert_encoding($subject,"iso-2022-jp","auto");
$content = "A様\nこの度はありがとうございました。\nBより";
$content = mb_convert_encoding($content,"iso-2022-jp","auto");
$from = "From:".mb_encode_mimeheader("差出人B","iso-2022-jp")."<b@bbb.com>";
mb_send_mail($to,$subject,$content,$from);
?>

これで送信したら、以下のようなメールが届きました。

From: 綏??坂査鐚 <[email protected]>
To: 鐚≧? <[email protected]>
件名: ◯◯の件について
本文:
A様
この度はありがとうございました。
Bより

原因

サーバーの内部エンコーディングとmb_encode_mimeheaderで使う文字は同じエンコーディング同士じゃないと文字化けするようです。今回の環境では以下のエンコーディングとなっています。

  • 内部エンコーディング:EUC-JP
  • フォームの入力値:UTF-8
  • メール送信:ISO-2022-JP

対処方法

  • 内部エンコーディング:EUC-JP
  • フォームの入力値:EUC-JP
  • メール送信:ISO-2022-JP

となるように、mb_encode_mimeheaderに使う文字列を内部エンコーディングに合わせて『EUC-JP』にしてみました。

<?php
mb_language("Ja") ;
$to = mb_convert_encoding("A様","euc-jp","auto");
$to = mb_encode_mimeheader($to,"iso-2022-jp")."<a@aaa.com>";
$subject = "◯◯の件について";
$subject = mb_convert_encoding($subject,"iso-2022-jp","auto");
$content = "A様\nこの度はありがとうございました。\nBより";
$content = mb_convert_encoding($content,"iso-2022-jp","auto");
$from = mb_convert_encoding("差出人B","euc-jp","auto");
$from = "From:".mb_encode_mimeheader($from,"iso-2022-jp")."<b@bbb.com>";
mb_send_mail($to,$subject,$content,$from);
?>

すると正常なメールが届きました。

From: 差出人B <[email protected]>
To: A様<[email protected]>
件名: ◯◯の件について
本文:
A様
この度はありがとうございました。
Bより

ブログの新着記事のリストを表示したいけど、そのページではPHPが使えない。ってときに使えます。また外部のブログのRSSを読み込みたい時に使えます。

まず、PHPで最新の投稿記事をブログのRSSから読み込み、動的な内容に合わせてJavascriptを書き出す。そしてHTMLページからJavascriptで呼出し表示します。

<?php
//読み込みたいXMLのパス
$rssurl = "http://hoshiya.biz/blog/index.xml?".date( "YmdHis", time() );
$rssdata = simplexml_load_file($rssurl);
//表示件数
$num_of_data = 5;
$outdata = "'<ul>'\n";
	for ($i=0; $i<$num_of_data; $i++){
		$pubDate = $rssdata->channel->item[$i]->pubDate;
		$pubDate = date('Y-m-d',strtotime($pubDate));

		$outdata .= "+'<li>'\n";
		$outdata .= "+'<small>". $pubDate . "</small>&nbsp;";
		$outdata .= "<a href=\"";
		$outdata .= $rssdata->channel->item[$i]->link;
		$outdata .= "\">";
		$outdata .= $rssdata->channel->item[$i]->title;
		$outdata .= "</a>'\n";
		$outdata .= "+'</li>'\n";
	}
		$outdata .= "+'</ul>'";
        
//↓これがないと書き出したスクリプトをJavascriptとして認識してもらえない
header("Content-type: application/x-javascript");
echo "document.write($outdata)";
?>

上記を呼び出すと以下の内容のJavascriptが書き出されます。(サンプル

'\n";
	for ($i=0; $i<$num_of_data; $i++){

		$pubDate = $rssdata->channel->item[$i]->pubDate;
		$pubDate = date('Y-m-d',strtotime($pubDate));

		$outdata .= "+'
  • '\n"; $outdata .= "+'". $pubDate . " "; $outdata .= "channel->item[$i]->link; $outdata .= "\">"; $outdata .= $rssdata->channel->item[$i]->title; $outdata .= "'\n"; $outdata .= "+'
  • '\n"; } $outdata .= "+''"; echo "document.write($outdata)"; ?>

    これをHTMLから以下のように読みこんで表示させます。

    
    

    すると以下のように表示されます。

    以下の環境にphpMyAdminをインストールしてみました。

    OS Windows 2012 Server(IIS8)
    PHP 5.4
    MySQL 5.6.11
    phpMyAdmin 4.0.0

    しかし、

    Cannot start session without errors, please check errors given in your PHP and/or webserver log file and configure your PHP installation properly.

    というエラーが出て苦戦...。でもなんとか以下の設定で解決できたのでメモ。

     

    phpMyAdminをダウンロード

    1. http://www.phpmyadmin.net/のダウンロードページからphpMyAdminをダウンロード
    2. 解凍して任意のサイトのディレクトリにコピー
      (例)C:\inetpub\wwwroot\phpmyadmin

     

    php.iniを変更

    • session.save_path = "/tmp"のコメント解除し有効化し、session.save_path = "C:\php\tmp"に変更。 php.iniがあるディクレクトリにtmpフォルダを作っておく(※ここが超重要)
    • extension=php_mbstring.dll をコメント解除し、エクステンションを有効化
    • extension=php_mcrypt.dll をコメント解除し、エクステンションを有効化
      自分の環境にはこの記載がなかったので無視
    • extension=php_mysqli.dll をコメント解除し、エクステンションを有効化

     

    config.inc.phpを変更

    • config.sample.inc.phpをconfig.inc.phpにリネーム
    • Cookie 認証用のパスフレーズを入力。内容については任意で決定。
      $cfg['blowfish_secret'] = '**任意**'
    • MySQL のサーバー名 (webサーバーと同一の場合は、 localhost のままで OK) を入力。
      $cfg['Servers'][$i]['host'] = 'localhost';
    • Uploadディレクトリを変更(フォルダも作成しておくこと)
      $cfg['UploadDir'] = 'C:\inetpub\wwwroot\phpmyadmin\upload';
    • Saveディレクトリを変更(フォルダも作成しておくこと)
      $cfg['SaveDir'] = 'C:\inetpub\wwwroot\phpmyadmin\save';

     

    アクセスしてみる

    実際にアクセスしてみて以下の画面が出れば設定成功
    (例)http://localhost/phpmyadmin/

    phpmyadmin

     

    その他

    無事にログインできたあとは以下も行っておきましょう。

    ワードプレスに投稿した記事を新しい順にリスト形式で表示する方法のメモ。

    <h2>新着情報</h2>
    <?php
    $posts = get_posts('numberposts=5&category=');
    global $post;
    ?>
    <?php if($posts): ?>
    <ul>
    <?php foreach($posts as $post):
    setup_postdata($post); ?>
    <li><?php the_time('Y年m月d日');?>&nbsp;<a href="<?php the_permalink();?>"><?php the_title(); ?></a></li>
    <?php endforeach; ?>
    </ul>
    <?php endif; ?>

    numberposts』は表示する『件数』

    『cat』は表示したい『カテゴリ』の指定しなければ全投稿で、「1,3,5」などカンマで区切れば細かく指定することもできるようです。

    初歩的なことですが、Wordpressの固定ページ編集の欄に記述したPHPを動かすには『Exec-PHP』などPHPを有効にするためのプラグインを入れないと、ソースが表示されるだけで動きません。

    役にたちそうなので、とりあえずメモ。

     

    Facebook Query Language (FQL) リファレンスで取得できる情報の種類を確認できます。

     

    Graph APIエクスプローラでリクエストに対して、取得できる実際のデータを見ることができます。タブを切り替えればFQL文を実行してみることもできます。

     

    PHP5のSimpleXMLでRSSを取得して新着投稿をリスト表示する。

    PHP5から使えるようになったSimpleXMLを使うとXMLの要素の内容を簡単に読み込むことができるようになりました。

    この機能を使って、変数にブログのRSSを読み込ませて新着記事を5件分表示するスクリプトを作成してみました。

     

    <?php
    
    //読み込みたいXMLのパス
    $rssurl = "http://hoshiya.biz/blog/index.xml";
    
    $rssdata = simplexml_load_file($rssurl);
    
    //表示件数
    $num_of_data = 5;
    
    $outdata = "<ul>";
    	for ($i=0; $i<$num_of_data; $i++){
    	  $outdata .= "<li>";
    	  $outdata .= "<a href=\"";
    	  $outdata .= $rssdata->channel->item[$i]->link;
    	  $outdata .= "\">";
    	  $outdata .= $rssdata->channel->item[$i]->title;
    	  $outdata .= "</a>\n";
    	  $outdata .= $rssdata->channel->item[$i]->pubDate;
    	  $outdata .= "</li>";
    	 }
      $outdata .= "</ul>";		 
    
    print $outdata;
    
    ?>
    
    

    こうしてできたこのブログの新着記事5件のリストの表示が以下。

     

    "; for ($i=0; $i<$num_of_data; $i++){ $outdata .= "

  • "; $outdata .= "channel->item[$i]->link; $outdata .= "\">"; $outdata .= $rssdata->channel->item[$i]->title; $outdata .= "\n"; $outdata .= $rssdata->channel->item[$i]->pubDate; $outdata .= "
  • "; } $outdata .= ""; print $outdata; ?>

     

    表示ができない場合は以下のように「channel->」を省いてみてください。

    $rssdata->item[$i]->title;

     

    参考ページ

    ライブラリをインクルードしてたった数行で、WEBスクレイピング(HTML内を部分的に取り出し、表示する)ができる恐ろしいPHPライブラリを見つけました。

    ライブラリは上記よりダウンロードできます。

    <?php
    
        include_once($_SERVER['DOCUMENT_ROOT']."/lib/simplehtmldom/simple_html_dom.php");
        
        $html = file_get_html('http://hoshiya.biz');  
           
        foreach($html->find('title') as $row)
        $row = $row->plaintext;
        $row = mb_convert_encoding($row, mb_internal_encoding(), "auto" );  
        echo $row;
    
    ?>

    たったこれだけで取得できます。

    find()で取り出したい条件や要素を記入するだけです。

    恐ろしく簡単で便利なのはタグはもちろん、idやclassも指定できるし、そのタグ自体を抽出することもできます。

    検索結果の一覧や、リンク集なども楽に抽出ができそうな感じです。

    その他の使い方などは「PHP Simple HTML DOM Parserマニュアルページ」を参照してみてください。

    参考サイト

    関連記事

    指定したURLのHTMLソースから目的のタグ内の文字列をSQL文で取り出すことができるライブラリを見つけました。

    今までは正規表現を使って文字列を取得していましたが、このライブラリならタグはもちろん、idやclassまで検索対象にできるスグレモノで、SQLの文法と配列が理解できれば、いろいろなことに使えそうです。

    このように「HTML内を部分的に取り出し、表示する」ことを「Webスクレイピング」というそうです。

    使用準備

    • ライブラリをダウンロードして任意のディレクトにアップロード。
    • 利用するファイルに「snoopy.class.php」と「htmlsql.class.php」をインクルード。

    使用例

    <?php
    
    include_once($_SERVER['DOCUMENT_ROOT']."/lib/snoopy.class.php");
    include_once($_SERVER['DOCUMENT_ROOT']."/lib/htmlsql.class.php");
    
    function getTitle($url){
    
    	$wsql = new htmlsql();
    	
    	// connect to a URL
    	if (!$wsql->connect('url', $url )){
    	print 'Error while connecting: ' . $wsql->error;
    	exit;
    	}
    	
    	// execute a query:
    	if (!$wsql->query('SELECT * FROM title')){
    	print "Query error: " . $wsql->error;
    	exit;
    	}
    	
    	// show results:
    	foreach($wsql->fetch_array() as $row){
    	
    	//print_r($row);
    	echo $row['text'];
    		
    	}
    
    }
    
    getTitle("http://hoshiya.biz");
    
    ?>

    ちなみに、print_r($row)とすると、$rowに格納されている配列の内容が確認できます。

    $rowの中身→ Array ( [tagname] => title [text] => 星屋工作室 )

    例文

    その他の例文はまた今度...。

    制限

    <div>の中の<div>など、同じタグに囲まれている文字列や要素はダイレクトに取得できず、一度大枠を取得して、再度その中から抜き出さなければならないようです。

    関連記事

    タイトルの通りですが、今まで使用できていたPHPのインクルードが急に使えなくなりました。

    PHPのバージョンを5.2から5.3に変更したからかもしれませんが、以下のエラーが出ます。

    Warning: include_once() [function.include-once]: http:// wrapper is disabled in the server configuration by allow_url_include=0 in/home/users/2/lolipop.jp-dp********/web/tracking/index.php on line 182

     

    結論からいうと、インクルードするファイルのパスをドキュメントルートで指定すれば解決です。

    <?php
    
    include_once "/home/users/2/lolipop.jp-dp********/web/include.inc";
    
    //または
    
    include_once $_SERVER['DOCUMENT_ROOT']."/include.inc";
    
    ?>
    

    include,include_once,require,require_onceも同様です。

     

    今までは、 ホストディレクトリを指定していたため、今回エラーになりました。

    <?php
    
    include_once "http://hoshiya.biz/include.inc";
    
    //または
    
    include_once "http://".$_SERVER['HTTP_HOST']."/include.inc";
    
    ?>
    

     

    これに気づくのにしこたま時間がかかりました...。

    解決できてよかったです。

     

    エラー文のallow_url_include=0が原因だと思って、ひたすらGoogleで検索しましたが、ロリポップにはphp.iniでallow_url_includeに関する設定項目がなく、困っていました。

    やれやれ...。

    以前に「 」の一部で タイトルタグ<title></title>の間の文字列を取得するスクリプトを紹介しましたが、もっと短くできました。

     

    <?php
    
    function getTitle( $url ) {
    	
    	$byte = 256;
    	
    	while(empty($matches)){
    		
    		//無限ループにならないようにバイト数を制限
    	
    		if($byte > 10000){ 
    	
    			break; 
    	
    		}
    		
    		//file_get_contents($url)でも読めるが、バイト数指定で読み込む
    		$html = file_get_contents($url, NULL, NULL, 0, $byte); 
    	
    		preg_match("@<title.*?>(.*?)</title>@i" , $html, $matches);
    	
    		$byte= $byte + 256;
    	
    	}
    
    	$html = $matches[1];
    	
    	$html = mb_convert_encoding($html, mb_internal_encoding(), "auto" ); 
    	
    	return($html);
    	
    }
    
    echo getTitle("http://hoshiya.biz");
    
    ?>

    タイトルタグが見つからなかったり、 タイトルタグ<title></title>よりも前に大量の文字列があると読み込みに時間がかかるので、読み込みのバイト数上限を決め、タイトルが見つかるまで徐々に読み込みバイト数を増やしていくようにしました。

    ↓上記でhttp://hoshiya.bizのタイトルを取得した結果

     

    20011/03/06追記

    PHPのクラスライブラリPEARのパッケージ(iHTTP_Client)を使った方法が見つかったのでメモ。

    こっちの方が高速!な感じがします...。

    ※PEARのパッケージHTTP_Clientと依存関係にあるHTTP_Request2が必要です。

    <?php
    
    function getTitle($targetUrl){
    	
    	require_once $_SERVER['DOCUMENT_ROOT']."/lib/PEAR/HTTP_Client/Client.php"; 
    	
    	$client =& new HTTP_Client();
    	$client->get($targetUrl); 
    	$response = $client->currentResponse(); 
    	
    	//余計な改行コードをスペースに変換
    	$response = str_replace( array( chr(10), chr(13), chr(9) ), chr(32), $response['body'] ); 
    	
    	preg_match("/<title.*?>(.*?)<\/title>/", $response, $title_matches); 
    	
    	$title = $title_matches[1];	
    	$title = mb_convert_encoding($title, mb_internal_encoding(), "auto" );  
    	
    	return($title);
        
    }
    
    echo getTitle("http://hoshiya.biz");
    
    ?>

     

    ついでにJavascriptでタイトルを取得する方法もメモ。

    ※現在のURLのタイトルしか取得できません。

    <script type="text/javascript">
    	document.write("このページのタイトルは→「"+document.title+"」です。");
    </script>

    結果:

    関連記事

    3文字のドメインが欲しい...。

    でも、0~9、a~zと-(ハイフン)の組合せをいろいろ想像してみたけど、

    検索してみると取得済み...。

    他に思いあらる3文字ってどんだけあるの?

    ということで、

      <?php
    // 配列作成
    $chars = array_merge(range(0,9),range('a','z'),array('-')) ;

    $x = 0;

    for($i = 0; $i < count($chars); ++$i) {
    $a = $chars[$i];

    for($j = 0; $j < count($chars); ++$j) {
    $b = $chars[$j];

    for($k = 0; $k < count($chars); ++$k) {
    $c = $chars[$k];

    $abc = $abc.$a.$b.$c."<br>";
    $x++;

    }

    }

    }

    echo count($chars)."種類の文字の組合せは「".$x."」パターンあります。<br>";
    echo $abc;
    "; $x++; } } } echo count($chars)."種類の文字の組合せは「".$x."」パターンあります。
    "; echo $abc; } ?>

    ※すべての組合せはサーバーに負荷がかかるので、ここでは英文字を省いて数字とハイフンのみの組合せを表示します。

    サンプル見つけたのメモ。

     

     

    すばらしい(涙)

    <?php
    function dec_to_b64($decnum) {
    $chars = array_merge(range(0,9),range('A','Z'),range('a','z'),array('+','/')) ;
    $result = '' ;
    for (; $decnum > 0; $decnum = floor($decnum/64)) {
    $result = $chars[$decnum%64].$result ;
    }
    return $result == '' ? '0' : $result ;
    }
    function b64_to_dec($b64num) {
    $chars = array_flip(array_merge(range(0,9),range('A','Z'),range('a','z'),array('+','/'))) ;
    $digits = array_reverse(preg_split('//',$b64num, -1, PREG_SPLIT_NO_EMPTY)) ;
    $result = 0 ;
    for($i = 0; $i < count($digits); ++$i) {
    if (!$chars[$digits[$i]]) return false ;
    $result += pow(64, $i) * $chars[$digits[$i]] ;
    }
    return $result ;
    }
    $dec = 1234567890 ;
    $b64 = dec_to_b64($dec) ;
    echo "<div class=\"block_1\">" ;
    echo "<p>10進数:".$dec."\n</p>" ;
    echo "<p>10進数を64進数に変換:".$b64."\n</p>" ;
    echo "<p>64進数を10進数にデコード:".b64_to_dec($b64)."\n</p>" ;
    echo "<p>64進数\"Hoshiya\"を10進数にデコード:".b64_to_dec('Hoshiya')."</p>" ;
    echo "</div>" ;
    ?>
    

    ちょっといじくったけど、以下がその結果。

    0; $decnum = floor($decnum/64)) { $result = $chars[$decnum%64].$result ; } return $result == '' ? '0' : $result ; } function b64_to_dec($b64num) { $chars = array_flip(array_merge(range(0,9),range('A','Z'),range('a','z'),array('+','/'))) ; $digits = array_reverse(preg_split('//',$b64num, -1, PREG_SPLIT_NO_EMPTY)) ; $result = 0 ; for($i = 0; $i < count($digits); ++$i) { if (!$chars[$digits[$i]]) return false ; $result += pow(64, $i) * $chars[$digits[$i]] ; } return $result ; } $dec = 1234567890 ; $b64 = dec_to_b64($dec) ; echo "
    " ; echo "

    10進数:".$dec."\n

    " ; echo "

    10進数を64進数に変換:".$b64."\n

    " ; echo "

    64進数を10進数にデコード:".b64_to_dec($b64)."\n

    " ; echo "

    64進数\"Hoshiya\"を10進数にデコード:".b64_to_dec('Hoshiya')."

    " ; echo "
    " ; ?>

     

     

    その他参考

    PHP:10進数を36進数に変換する。

    • 投稿

    10進数を36進数に変換する関数

    base_convert("変換したい文字列", $from_base, $to_base);
    
    	//(例)base_convert(12345, 10, 36); //10進数の12345を36進数に変換します。
    	//(例)base_convert("12345", 36, 10); //36進数の12345を10進数に変換します。
    

     

    ちなみに、進数は何個、数を数えたら次の桁に繰り上がるかの数。

    2進数 0,1の2数
    10進数 0~9の10数
    16進数 0~9、A~Fの16数
    36進数 0~9、A~Zの36数

     

    変換フォーム

    10進数

    10進数の「」は、36進数で表すと「」です。

     

    この関数でできない62進数(0~9、A~Z、a~z)やBASE64を応用した64進数にも挑戦したいと思います。

     

    追記2011/02/14

    イントラネットで表示されているページを印刷しようとすると、A4・で印刷したいのに、デフォルトはA4・になっているため、印刷設定を毎回「」に変更しなくてはならない事にガマンの限界が...。

     

    イントラネットはWindowsサーバー上IISでASと一部PHPで作っています。

     

    印刷設定(用紙設定)はASPやJavascriptの関数があるんかな?

    といろいろ検索しましたが見つかりませんでした...。

     

    しかし、替わりに見つけたのはActtiveXコントロール「ScriptX」を使った方法!

    まず以下のページで「Dowload smsx.cab」ボタンを押してダウンロード

    任意のディレクトリにアップロード

    印刷設定を使うページに以下のコードを挿入し、

    <object>タグでActiveXコントロール読み込む。

    <!-- ScriptX 読み込み -->
    <object id=factory style="display:none"
     classid="clsid:1663ed61-23eb-11d2-b92f-008048fdd814"
     codebase="http://**smsx.cabを設置した場所のパス**/smsx.cab#Version=6,5,439,72(←バージョンによって書き換える)">
    </object>
    <!-- ScriptX 読み込み -->
    

    次にJavascriptファンクションで印刷設定を行う。

    <script type="text/javascript">
    	function printWindow() {
    		factory.printing.header = "ヘッダ名";
    		factory.printing.footer = "フッタ名";
    		factory.printing.portrait = false; // 用紙方向 true: 縦 false: 横
    		factory.printing.leftMargin = 1.0;
    		factory.printing.topMargin = 1.0;
    		factory.printing.rightMargin = 1.0;
    		factory.printing.bottomMargin = 1.0;
    		factory.printing.Print(false); // 印刷実行 ture: 印刷ダイアログなし false: 印刷ダイアログあり
    }
    </script>
    

    あとはファンクションを呼び出すだけでOK!

     <input type="button" value="ScriptXで印刷" onclick="printWindow();" />
    
    自分の場合は印刷ページ表示と同時に印刷するので、
     <body onload="printWindow();">
    

    としました。

     

    ※初回使用時は「ActiveXをインストールしますか?」見たいな警告が出ますが、インストールしてしてください。

     

    その他

    ヘッダ・フッタに、現在日・ページ数出力

    factory.printing.header = "ヘッダ名 &b 日付: &d";   // 現在日出力
    factory.printing.footer = "フッタ名 &b &p/&P ページ";     //   ページ数出力
    

    これでイントラネットとインターネットでヘッダー・フッター印刷を切り分けられそうなのがいいです。

    ヘッダーとフッターで使える記号

    • &w : 印刷するホームページのタイトル
    • &u : 印刷するページのアドレス
    • &d : 現在の日付(xxxx/xx/xx 形式)
    • &D : 現在の日付(xxxx年xx月xx日 形式)
    • &t : 現在の時刻(コントロールパネルの「地域」で設定されている形式)
    • &T : 現在の時刻(xx:xx:xx 形式)
    • &p : 現在のページ番号
    • &P : 総ページ数
    • &b : 右揃えの文字列(「&b」に続けて文字列を入力)
    • &b&b : 中央揃えの文字列(最初の「&b」に続けて文字列を入力)と右揃えの文字列(2 番目の「&b」に続けて文字列を入力)
    • && : アンパサンド(&)

     

    直接印刷(印刷ダイアログ表示なし)だけを直接使う

    factory.printing.Print(true);
    

     

    プレビュー画面を表示

    factory.printing.Preview();
    

     

    ActiveXコントロールだけにWindowsサーバー上ブラウザがIEじゃないと動かないとは思うのですが、WindowsサーバーであればIISじゃなくてもApatchでも動き、<object>タグで「smsx.cab」さえ読み込めばPHPでも使えるようなことが書かれたページがありました。

     

    有償版もあるようですが、用紙サイズの指定とかもできるみたいです。