2010年1月8日
HTMLページをパースしてURLを取り出す処理を書いていたのですが、ページ内のリンクなどが全部絶対URLで記述されていれば非常に楽なのですが、現実としてそうでもなく、ページによっては相対パスで書かれていたりして、正規表現で偏にリンクからURLを抜き出すだけではうまくできませんでした。
そこで少しググってみたら
PHPで相対パスから絶対URL(URI)を作成する|PHPプログラムメモ|プログラムメモ
という記事を発見!おぉ、これは便利!
と思って使わせてもらおうと思ったのですが、いくつかテストしてみて、相対パス処理で不備があるなーと思ったところがあったのでちょっと改良させてもらいました。
37~38行目は正直いらない気がしたのですが、 PHP 5.3 のCLIでWindows上でテストした際に、なぜか \/ (アルファベットのVではなく、\ と / ) で出力されたのが気になったので、無駄かもしれないけどあえて記述。
あと $parse の初期化もここまでする必要ないけど、念のためNotice対策を…w
相対パスから絶対URLする関数
PHP:
-
<?php
-
/**
-
* 相対パスから絶対URLを返します
-
*
-
* @param string $base ベースURL(絶対URL)
-
* @param string $relational_path 相対パス
-
* @return string 相対パスの絶対URL
-
* @link http://blog.anoncom.net/2010/01/08/295.html
-
* @link http://logic.stepserver.jp/data/archives/501.html
-
*/
-
function createUri($base = '', $relational_path = '') {
-
-
-
'scheme' => null,
-
'user' => null,
-
'pass' => null,
-
'host' => null,
-
'port' => null,
-
'path' => null,
-
'query' => null,
-
'fragment' => null,
-
);
-
-
-
if (preg_match ( '#^https\://#',
$relational_path )) {
-
// 相対パスがURLで指定された場合
-
return $rel_path;
-
} elseif (preg_match ( '#^/.*$#',
$relational_path )) {
-
// ドキュメントルート指定
-
return $parse['scheme'] . '://' . $parse ['host'] . $relational_path;
-
} else {
-
// 相対パス処理
-
-
$relPath =
explode ( '/',
$relational_path );
-
foreach ( $relPath as $relDirName ) {
-
if ($relDirName == '.') {
-
-
-
} elseif ($relDirName == '..') {
-
-
if ( count ( $basePath ) ==
0 ) {
-
-
}
-
} else {
-
-
}
-
}
-
$path =
implode ( '/',
$basePath );
-
return $parse ['scheme'] . '://' . $parse ['host'] . $path;
-
}
-
}
テストケース
ベースURL
http://example.com/path/to/url
相対パス
- /
- /index.html
- /foo/bar/baz/
- ./foo/bar/baz
- ../../../foo/bar/baz/index.html
- foo/bar/baz.html
- foo/bar/baz/../index.html
テストコード
PHP:
-
<?php
-
$base = 'http://example.com/path/to/url';
-
-
$pathes[] = '/';
-
$pathes[] = '/index.html';
-
$pathes[] = '/foo/bar/baz/';
-
$pathes[] = './foo/bar/baz';
-
$pathes[] = '../../../foo/bar/baz/index.html';
-
$pathes[] = 'foo/bar/baz.html';
-
$pathes[] = 'foo/bar/baz/../index.html';
-
-
foreach ( $pathes as $path ) {
-
echo createUri
($base,
$path) .
"\n";
-
}
結果
こんな感じ
http://example.com/
http://example.com/index.html
http://example.com/foo/bar/baz/
http://example.com/path/to/foo/bar/baz
http://example.com/foo/bar/baz/index.html
http://example.com/path/to/foo/bar/baz.html
http://example.com/path/to/foo/bar/index.html
タグ: PHP, URL
カテゴリー: PHP | コメントはまだありません »
2009年11月7日
PHPでWebアプリケーションなどを開発していて、SQL文を発行する際に、セキュア面や利便性などから、ADODBやPDOなどを用いて、Prepared Statementを使うSQLを書くこともあると思います。
その際、特にINSERT文などはカラムの数だけVALUESの中に ? が並ぶことになるかと思います。
SQL:
-
-- 例:
-
INSERT INTO
-
`persons` (`id`, `name`, 'age`, `birthday`, `mailaddress`, `phone`, `zipcode`, `address`)
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?);
このとき、 ? がひたすら並んでいるだけとなると非常に見づらく、INSERTする情報が多くなってくると、指定したカラム数と VALUESの ? の数が一致せず、
Number of variables doesn't match number of parameters in prepared statement
といったエラーに遭遇したことが一度はあるかと思います。
特に、プログラムの改修をする際などは、カラム名だけ追加して、うっかり VALUESの ? だけ追加のし忘れなどをしてしまうことなんかも。。。
そこで、Prepared Statementを作る際のINSERT文のSQLを簡単で分かりやすくしたいと思います。
PHP:
-
<?php
-
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
-
$user = 'dbuser';
-
$password = 'dbpass';
-
-
try {
-
$db = new PDO($dsn, $user, $password);
-
-
// INSET対象となるカラム名を指定
-
-
'id',
-
'name',
-
'age',
-
'birthday',
-
'mailaddress',
-
'phone',
-
'zipcode',
-
'address',
-
);
-
-
-
1 => 'anon',
-
2 => 'anon',
-
3 => '25',
-
4 => '1984-05-02',
-
5 => 'root@example.com',
-
6 => '03-xxxx-xxxx',
-
7 => 'xxxxxx',
-
8 => 'Tokyo',
-
);
-
-
$sql = 'INSERT INTO persons '
-
-
. ') VALUES ('
-
-
. ')'
-
;
-
-
/*
-
// またはテーブル名やカラム名を明示的にクオートする場合はこちら
-
$sql = 'INSERT INTO `persons` '
-
. '`' . implode('`, `', $columns) . '`'
-
. ') VALUES ('
-
. implode(', ', array_fill(0, count($columns), '?'))
-
;
-
*/
-
-
$stmt = $db->prepare($sql);
-
-
foreach($binds as $key => $value){
-
$stmt->bindValue($key, $value);
-
}
-
-
return $stmt->execute();
-
-
} catch (Exception $e) {
-
error_log('[' .
get_class($e) .
'] ' .
$e->
getMessage() .
' in ' .
$e->
getFile() .
' on line ' .
$e->
getLine());
-
}
要点は、 $columnsという配列にカラム名を配列で持たせ、Prepared INSERT文を発行する際に、implode()関数でそのカラム名をカンマ区切りで連結、VALUESの ? は array_fill()関数で、カラム名の配列の値の数だけ ? で埋めた配列を作成し、さらにそれをimplode()関数で連結していく。
というだけです。
バインドの個所は今回手抜きにしてしまいました。
本当はバインドも同じようにもう少し見直せばもっと分かりやすく、簡潔にできると思うのですが、
いい書き方が浮かびませんでした。。。
タグ: PHP, TIPS
カテゴリー: PHP, 開発 | コメントはまだありません »
2009年10月26日
先日発売された Windows 7 Professional を早速インストールし、その直後にアンインストールしてみました。
…というのも、インストール時に、複数ある物理ドライブのうち、本来インストールしたかったドライブとは別のドライブ(データ領域として利用していたところ)にインストールしてしまったためです。。。
で、今回は早速のアンインストールを実施してみました。
まずは ブートマネージャのリストからの削除。
Windows 7 RC を削除する方法:bcdedit - Windows Vista とのデュアルブート
http://seawind.air-nifty.com/day/2009/07/windows-7-rc-bc.html
上記の記事や、ほかにもググるといくつかブートマネージャからの削除方法が既に書かれています。
このあたりはこの通りやればできるので、今回割愛します。
続いて、OS本体のアンインストール(削除)
上記の作業だけだと、OS本体は残ったままなのでOSも消しましょう。
方法についてはマイクロソフトからも
Windows 7 のアンインストール方法
http://support.microsoft.com/kb/971762/ja
というアナウンスがされています。
今回の場合は、上記の記述の中の「状況 2」のケースに近いのですが、残念ながらデータ領域であったため、「空の領域」ではなかったんですね。
で、データの量も多いため、データを別の領域に待避して、クリーンインストールとかフォーマットとかはなるべくしたくないんです。。。
そこで Windows の削除です。
今回のインストールで作成された領域は、ドライブ直下にある
- Program Files
- Program Files (x86)
- ProgramData
- Windows
- Windows.old
- Users
のみ。("Program Files (x86)"は64ビット版のみ)
これらを削除したいのですが、通常通りに削除しようとすると、OSの権限などによって削除することができません。
(たとえ起動中のOS領域とは別のところにあっても)
そこで、いくつかの手順を踏んでがんばって削除してみました。
この投稿の続きを読む »
タグ: Windows
カテゴリー: PC, ネタ | コメントはまだありません »
2009年8月25日
Linux OS環境にて、絶対実行してはいけないけど、一度でいいからしてみたい。
rm -rf / を実行してみた。
rm -rf とは…
rm とは removeの略で、取り除く、除去、削除といった意味。ここではファイルを削除するコマンドとなる。
-rf とは、rm コマンドのオプションで、 -r が Recursive の頭文字で「再帰的に」を表す。この場合、再帰的にファイル(とディレクトリ)を削除する。
-f は Force の頭文字で、「強制的に」を表す。通常はファイルを消す際に、消していい?と確認されるが、このオプションを付けると有無をいわず削除を行う。
最後の / は削除の対象となるパス。 / はUnixにシステムにおけるルートパス。Windowsでいう C:\ を表すのと同じようなもの。
つまり、このコマンドの指す意味は、 / (ルートパス)以下の全てのファイルとディレクトリを強制的に削除するという恐ろしいコマンド。
通常は、一般ユーザで実行しても、ファイルの所有権限などの制限により、システム的に必要なファイルが消えることがないように設計、設定されているが、今回はUnixシステム上最高特権となる root (Windowsで言うとAdministrator相当)ユーザでこれを実行してみる。
この投稿の続きを読む »
カテゴリー: Linux, PC, ネタ | コメントはまだありません »
2009年6月18日
ついに一般向けアップデート提供開始来ました!
その内容は既に発表済みでありますが、以下のものとなっているようです。
iPhone OS 3.0 ソフトウェア・アップデート
このアップデートには、以下の機能を含む、100 以上の新機能が含まれています:
• カット、コピー&ペースト、シェイクによる取り消し
• 主要アプリケーションにおける横表示キーボード
• SMS/MMS アプリケーションの強化
- 写真、連絡先、オーディオファイル、および位置情報を MMS で送受信*
- メッセージを 1 つずつ、または複数まとめて転送および削除
• メール、カレンダー、メモ、および iPod 内の検索機能を追加
• iPhone 全体を Spotlight 検索
• カレンダーで CalDAV およびカレンダーの登録をサポート
• Safari の改良
- パフォーマンス
- HTML 5 をサポート
- オーディオおよびビデオの HTTP ストリーミング
- ユーザ名とパスワードの自動入力
• 新しいボイスメモアプリケーション
• Mac または PC と、iTunes 経由でメモを同期
• USB および Bluetooth 経由でインターネットテザリング*
• iTunes Store からムービー、テレビ番組、オーディオブックをブラウズおよびダウンロード**
• ステレオ Bluetooth***
• Wi-Fi 自動ログイン
• 株価アプリケーションの強化
• アプリケーション、ミュージック、ムービー、およびテレビ番組のより詳細なペアレンタルコントロールオプション
• iTunes アカウントの作成およびログイン**
• YouTube アカウントのログインおよび、登録チャンネル、レート、お気に入りへのアクセス**
• シェイクでシャッフル
• 新しい言語、辞書、およびキーボード
• MobileMe で利用可能な“iPhone を探す”および“リモートワイプ”(登録が必要)**
• より多くの Exchange ポリシーをサポート
• Exchange のミーティングの招待を作成および送信
• サーバ上のメールを検索(Exchange Server 2007 およびサポートされている IMAP サーバ)
• LDAP カンパニーディレクトリを検索
• VPN オンデマンドおよび VPN プロキシをサポート
• 暗号化された構成プロファイル
• 暗号化された iTunes バックアップ
• 以下を含む、1,000 におよぶデベロッパ API:
- アプリケーション内での購入
- Apple Push Notification Service(プッシュ通知サービス)
- アクセサリサポート
- ピアツーピア接続
- 地図の埋め込み
- iPod ライブラリのアクセス
• 不具合の修正
このソフトウェア・アップデートと互換性のある製品:
• iPhone
• iPhone 3G
• iPhone 3G S
* iPhone 3G および iPhone 3G S のみ対応。お使いのワイヤレスプロバイダによるサポートも必要。
** 一部の地域や言語では利用できません。
*** iPhone 3G および iPhone 3G S のみ対応。
機能の説明と詳しい手順については、次の Web サイトでお使いの iPhone のユーザガイドを参照してください:
<http://www.apple.com/jp/support/manuals/iphone>
iPhone について詳しくは、次の Web サイトを参照してください:
<http://www.apple.com/jp/iphone>
お使いの iPhone の問題を解決する、または追加のサポート情報を確認するには、次の Web サイトを参照してください:
<http://www.apple.com/jp/support/iphone>
このアップデートのセキュリティに関する内容について詳しくは、次の Web サイトにアクセスしてください:
<http://support.apple.com/kb/HT1222?viewlocale=ja_JP>
目玉はコピー&ペースト、MMSサポート、Push Notification Service (アプリ経由でのポップアップ通知)、 メモとメールでのランドスケープ入力対応、Spotlight検索、テザリング機能などです。
テザリングについては残念ながら日本国内においてはソフトバンクが現時点で提供の予定なしとのことですが、MMSについては既存の携帯電話サービス同様に提供されるようで、メールアドレスも @softbank.ne.jp のアドレスを付与されるようです。
さり気なく Wi-Fi 自動ログイン機能や、オートフィル機能、YouTubeのアカウント連携、Bluetoothのプロファイルの追加などなど、便利そうな更新が含まれています。
カテゴリー: iPhone | コメントはまだありません »
2009年4月5日
昨日(4月4日)、昨日発売したばかりの ASUS EeePC 1000HE を買ってきました。
というわけで開封の様子から…。







まず見た目。デザインなど。
今回はカラーはシルバーを購入。今までのEeePCシリーズは基本的に白か黒しかなかったけれど、今回のものは日本限定でシルバーが加わっています。
限定だからというわけではないのだけれど、シルバーではちょっと見た目がアルミ風なものとなっていて、見た目の重量感が増して、いい感じ。
それと、今までのEeePCは、液晶のフレーム部分がつや消しのプラスチックだったりして、見た目的にどうも安っぽさが抜けないため(実際安いのだけど)それでEeePCはあまり好きではなかったというのが正直合った。
けど、今回のはどれもつやありのフレームになったし、本体も全体的に変わって、今までに比べて高級感が増してるのがよかった。
ただ、シルバーはよく見ると実際にはアルミではなく、"アルミ風"な塗装が施されているだけ。実際にアルミ素材使ってたらもと高くなってるか。
キータッチについてはキーの感覚が広くなって、ボタンとボタンの間が空いているため、文字の打ち間違いも軽減できると思う。
ただ、キータッチが荒い(力強い)人が使うと、キーボードが若干ゆがみそう。(当たり前か)
少々気にしていたものとして、YouTubeなどの動画サイトを見た際に動画がカクカクしてしまわないかということがあったのだけれど、HD画質動画を見ても全く問題ないレベルだったのでここも満足。
ただ、さすがにニコニコはコメントが大量に流れてくると若干カク付き始めるかな。
そうそうあと、今回はOfficeなしモデルを買ったけど、後から別途購入済みのOffice 2007を入れたりもしました。
Officeについてはまだちゃんと使用していないため、使用感のレビューは後ほど書けたら書きます。
あとはメモリー。環境を作っていっていろいろと入れていって、デスクトップとほぼ同じくらいまでの環境を整えてみましたが、それだけでメモリーを760MBほど使用する状態にまでしてました。
なので使っていないIMなどを終了させてみたもののまだ530MBほど使用している。
やはりFirefoxのメモリー消費量が激しいか。と思ってみたものの、Firefox自体はそのうちの116MBしか使ってなかった。
ということは別の何かが残り400MB使っていると思うのだけど、それ以外に大量に目盛りを消費しているものはプロセス上からは確認することが出来なかった。
なので余裕を見越してメモリーはやっぱり2GBに転載しておいた方がいいかも。
というわけでざっくりなレビューもどきを書いてみました。
バッテリーの持ちなどはまだ体感的なものは確認できていないため、また書けそうなものがあったら追記してみたいと思います。
タグ: EeePC, UMPC, ネットブック, レビュー
カテゴリー: PC, モバイル | コメントはまだありません »
2009年4月5日
4月4日に発売された、バッテリー稼働時間9.3時間を誇るASUSのネットブック「EeePC 1000HE」を昨日(つまりは当日に)買ってきました。
バッテリ時間が従来のネットブックの中では現在最長の9.3時間ということと、CPUが従来のEeePCのAtom N270 1.60GHz からAtom N280 1.66GHz にグレードアップしてること、IEEE 802.11n(Draft 2.0)に対応してることに惹かれました。
本当は先日までは同じASUS製の「N10Jc」を買おうと思っていたのですが、GPUも使えたらいいけど、実際それほど使わないかなと思い、モバイルネットをするに当たり一番重要となるバッテリの持ち時間が一番長いこちらに決めました。
自分にとって久しぶりのノート型。前回のノートは8年前に買ってもらったVAIOノート VAIO PCG-XR7S。あれは3kgもあって重くて持ち歩く気にもならなかった。。。
今回これを買った理由は、外でのネット環境を整えたかったこと。
これについてはいくらかはiPhoneでまかなえるのだけど、やはりそれだけではできないこともまだまだある。
あとは出先で何らかの緊急対応を必要とする際にその場ですぐに対応できるように。
あとは外でほかのエンジニアの人とその場でコーディングし合うなんてことも出来たらいいなぁと思っていたため。
そして恐らく今後いろいろと機会も出てくるであろう、Genesis Lightning Talksなどの発表の場でプレゼンをする際に必要になるだろうと思ったため。
今はまだモバイルデータ通信のためのデータカードもないし契約もしてないけれど、それも後々、近いうちにしたいなーと思ってます。というかすると思う。
近く、会社の研修旅行で韓国に行くことも決まっているため、その際にも持って行きたいなぁと思ってます。
現地ではWibroというWiMAXをレンタルする予定。
と、今後はようやく手に入れたこのモバイル環境を活かしていろんなことが出来たらいいなぁなどと妄想しております。
初ネットブックなのでほかとの比較対象がないけれど、後のエントリーで簡単な使用感レビューを書いてみます。
カテゴリー: 無分類 | コメントはまだありません »
2009年3月7日
先日注文した、supercellのCDが届き、先ほどようやく手にして聞くことが出来ました。
…というのは、発売日の前日には家に届いていたのだけど、今日まで日中荷物を受け取れる人が家にいなかったため今日になったという…。

そんなことはさておき、CDの方ですが、収録楽曲はすべてリマスタリング・リミキシングされており、さらにギターとベースは一部の曲で生音となっています。
ベースは夏コミC74でもアルバムに参加していた「ティッシュ姫」(「こくまろ "姫" みるく」名義で参加)。
今まで「初音ミク」がなんたるかを知らなかった人にも是非とも聞いてみてもらいたいと思う一枚でした。
収録曲のサンプルをsupercellの公式ページで聞くことが出来ます。
そうそう、発売初日のオリコンデイリーアルバムランキングには、有名大物アーティストを差し置いて2位にランクインしていましたね。

おめでとうございます!
カテゴリー: VOCALOID, 話題 | コメントはまだありません »
2009年2月26日
Genesis Lightning Talks #13 (通称GLT)に行ってきました。
…と、本当は書きたかったのだけれど、諸事情により懇親会のみの参加となってしまった。
初参加にして懇親会だけとか何様よ…。
さらにその懇親会にすら遅刻してしまいましたが。。。
と、今回思うように参加できなかったのですが、懇親会だけでも色んな人とお話しできて良かったなぁと思ってます。
デブサミ以降、あちこちのこうしたイベントには積極的に参加していきたいなと言う意識は、以前に比べて格段に増えたなぁ。
今までの自分は色んな意味で引きこもってたけど、やっぱりこういうイベントや勉強会、交流への参加って大事だなと改めて感じてます。
(といってもデブサミからはまだ日は全然経ってないけど。)
やっぱり職種が同じにしろ違うにしろ、普段の自分の環境とは違う人たちと話しをしたり、情報を交換し合うってすごく大事だし、むしろ楽しいなと思ってくるようになった。
会社や家に引きこもってても、得られる情報はせいぜいネットか書籍だけ。でもそれ以外の場所から様々な情報を仕入れたり、また話の流れで話題が広がって元の話題からはちょっとずれた話をし合うのもなかなか良い。
こうして外の人と触れ合っていくと、自然と自分の中にあるものが刺激されて、自分ももっと情報を出していこうと思うようになる。
と、言うのはたやすいが、普段の自分は高確率で聞き手側でしかないので、もっと自分から情報を出して話していけるようにはなりたい。
そこが今後の課題。
その代わり…にはならないけど、最近になってようやくこのブログを活用したりして、外に情報を出すようにしているつもりではある。
今はまだうまくできないけど、本当に、社内とかの狭い範囲の中ではなく、多くの人に向けて、いつかは何らかの形でスピーカーとして人の前で何かを発表できるような形にしていきたい。これは本当に。自己成長のためにも。
…とまぁ、タイトルからは全く関係ないネタになってしまったけれど、来月こそは最初から参加できるようにしたい。出来ることなら最初は聴講者からスタートでw
タグ: GenesisLightningTalks
カテゴリー: イベント | コメントはまだありません »
2009年2月23日
車輪の再発明になっている可能性大な気がしますが、PHP4で動作する、動的な簡易クラスローダを作成してみました。
大まかにはZend FrameworkのZend_Loaderを参考にしていますが、基本的に1から書き直していています。
PHP:
-
<?php
-
/**
-
* 簡易クラスローダ
-
* for PHP4
-
*
-
* @author anon <anon@anoncom.net>
-
*/
-
class ClassLoader
-
{
-
function ClassLoader() {}
-
-
/**
-
* 指定されたクラスを読み込み、インスタンスを返します。
-
*
-
* @param string $class クラス名
-
* @param string|NULL クラスディレクトリ
-
* @param boolean $once requireでファイルを読み込む際に、require_onceで読み込むか否か
-
* @param array|NULL $param インスタンス生成時に引き渡す引数
-
* @param string|NULL $loaderMethod インスタンス生成時に呼び出される、コンストラクタ以外のメソッド名(Singletonパターンでの呼び出しの場合など)
-
*/
-
function loadClass($class, $dir = NULL, $once = TRUE, $params = NULL, $loaderMethod = NULL)
-
{
-
-
-
$classfile_exists = false;
-
foreach($dirs as $dir){
-
$filepath = $dir . '/' . $class . '.php';
-
if(Froute_Loader::isFileAvailable($filepath)){
-
$classfile_exists = true;
-
break;
-
}
-
-
}
-
if(!$classfile_exists){
-
trigger_error('could not load class, causes class file"' .
$class .
'" is not found.',
E_USER_WARNING);
-
}
-
}else{
-
$filepath = $dir . '/' . $class . '.php';
-
if(!ClassLoader::isFileAvailable($filepath)){
-
trigger_error('could not load class, causes class file "' .
$filepath .
'" is not found.',
E_USER_ERROR);
-
}
-
}
-
-
if($once){
-
require_once $filepath;
-
}else{
-
require $filepath;
-
}
-
-
-
trigger_error('could not load class, causes undefined class name "' .
$class .
'".',
E_USER_ERROR);
-
}
-
-
-
-
trigger_error('could not load class, causes undefined function name "' .
$class .
'".',
E_USER_ERROR);
-
}
-
-
-
}else{
-
-
}
-
}else{
-
/*
-
if(!function_exists($class)){
-
trigger_error('could not load class, \'causes undefined function name "' . $class . '".', E_USER_ERROR);
-
}
-
*/
-
-
$instance = new $class;
-
}else{
-
//$instance = new call_user_func($class, $params); // to use php5
-
$instance = new $class($params); // to use php4
-
}
-
}
-
return $instance;
-
}
-
-
/**
-
* ファイルが存在するか確認します
-
*
-
* @param string $filename
-
* @return bool
-
*/
-
function isFileAvailable($filename)
-
{
-
-
return true;
-
}else{
-
return false;
-
}
-
}
-
}
使い方は以下の通り
この投稿の続きを読む »
タグ: PHP
カテゴリー: 無分類 | コメントはまだありません »