2011年3月31日木曜日

「lexicon (XLLEX.DLL)が見つからないか、または壊れています。」の修復

Windows XPでMS Office 2007のアプリを起動できなくなった問題に対して、試行錯誤した上で何とか回復できたことのメモ。
回り道が多くて余分なこともしてると思うが、誰か(あるいは自分)の役に立つかもしれないので記録しておく。


いつものようにExcelを開こうとすると「lexicon(XLLEX.DLL)が見つからないか、または壊れています。」というエラーメッセージが表示され、Excelが開けない。
また、Wordも開かなくなっている。(開こうとすると何も書かれていなくてOKボタンしかないダイアログが表示される。)
XLLEX.DLLというファイルはOfficeのフォルダにあるので、レジストリがおかしくなっている?

Googleで調べてみたが、Windowsを再インストールするか、あるいはWindowsユーザーを新しく作り直すしか対策が見つからない。(それは嫌だ。)

「プログラムの追加と削除」でOfficeをアンインストールして、OfficeのインストールCDから再インストール。しかし状況変わらず。何回か繰り返したが駄目。

Windowsの「システムの復元」を使って、Excelが開けた頃にWindowsを戻す。

Excelを立ち上げようとすると、これまでとはまた別のエラーが出るようになった。
それに対してOfficeを再インストールしようと試みるも、そもそもアンインストールができない

  • 「プログラムの追加と削除」から「変更」「削除」ボタンを押しても、数秒固まるだけで何も起きない
  • OfficeのインストールCDのSetup.exeを起動すると、インストールエラーが発生して終了してしまう
この状態でインストールしようとしてもエラーになってインストールできない。

Microsoft Office 2007をアンインストール(削除)ができない|星屋工作室で紹介されているMSのサイトの「Fix it で解決する」というのをダウンロードして実行したら、Officeをアンインストールできた。

CDからOfficeを再インストール。

ExcelもWordも使えるようになった!


もしかしたら最初からFix itを使えば解決したのかもしれない。
Office2007だけでなく、2003や2010もアンインストール用の「Fix it」があるようだ → コントロール パネルからアンインストールできない場合、Office 2003、Office 2007 または Office 2010 スイートをアンインストールする方法


また、この後Microsoft UpdateによるOffice2007 SP2のインストールがどうしても失敗する事象が発生。

Office2007のサービスパックが当たらない - りぶろくを参考にWindows Installer 4.5をダウンロードしてインストール

SP2もインストールできた。

2011年3月25日金曜日

プログラム言語とフレームワークのオンラインマニュアル29選


Webで公開されている、プログラム言語・フレームワーク・DBのマニュアル(リファレンス)サイトへのリンクをまとめてみた。
選んだ基準は、できるだけ日本語で、なるべく分かりやすいこと。それを満たすなら公式リファレンスより非公式のものを優先している。



JavaScriptのマニュアルは他にも色々あり、使う人のレベルや用途によってどれが使いやすいかが変わってくると思うが、昔大変参考にさせて頂いた杜甫々版を挙げておいた。

Python、Perl、Objective-Cについては公式/準公式のリンクを書いたが、有志によるマニュアルでもっと良いものがあるのかもしれない。(これらの言語はあまり使わないので知らない。)

2011年3月24日木曜日

PHPで URLのホスト名(ドメイン)が存在するかチェックする方法

PHPでURLのホスト名(ドメイン)が有効なものかどうかをチェックする例。
file_get_contents()でignore_errorsをtrueにしてstream_context_create()してもホスト名が名前解決できなくてWarningが出てしまう問題に悩んでいる場合などにどうぞ。

$url = 'http://www.example.com/path';

$array = parse_url($url);

if ($array && $array['host']) {
    $ip = getHostByName($array['host']);
    $long = ip2long($ip);
  
    if ($long === false || $ip !== long2ip($long)) {
        echo '名前解決できなかった';
    } else {
        echo 'OK';
    }
} else {
    echo 'URLが正しくない';
}

DNSで名前解決できたらOKにしている。
また、ホスト名がIPアドレス(IPv4)の場合はどんなIPでも(たとえ255.255.255.255でも)OKにしている。

ip2long()で得た値をlong2ip()でIPアドレスに戻してチェックしているのは、ip2long()が「0.0.256」のような値を「0.0.1.0」などと解釈してしまうため。
参考:(IPv4) インターネットプロトコルドット表記のアドレスを、適当なアドレスを有する文字列に変換する - PHP 5.3 日本語マニュアル
ip2long() を、それ単体で IP の検証に利用するべきではありません。long2ip() と組み合わせて利用します。

<?php
// IP が有効であることを確認します。また、不完全な形式の IP を
// 以下で示すような正しい形式(ドットで 4 つに区切られている)に変換します。
$ip = long2ip(ip2long("127.0.0.1")); // "127.0.0.1"
$ip = long2ip(ip2long("10.0.0")); // "10.0.0.0"
$ip = long2ip(ip2long("10.0.256")); // "10.0.1.0"
?>


これはIPv4を使ってるけど、今後IPv6が普及したら...その時までにPHPも進化しているでしょう。


参考

2011年3月23日水曜日

PHPの SimpleXMLを配列に変換する

シンプルなXMLなら、SimpleXMLElementオブジェクトをarrayにキャストするだけで連想配列に変換できる。

$xml = '<?xml version="1.0" ?>
<root>
<test>TEST1</test>
<test>TEST2</test>
<attr trouble="MISSING">WHY?</attr>
</root>';

$sx = simplexml_load_string($xml);

var_dump((array)$sx);

array(2) {
  ["test"]=>
  array(2) {
    [0]=>
    string(5) "TEST1"
    [1]=>
    string(5) "TEST2"
  }
  ["attr"]=>
  string(4) "WHY?"
}

同じ要素名の要素がある場合(上記の例ではtest要素)、まとめて添字が0から始まる配列になる。
しかし、なぜか属性とテキストノードの両方がある要素の属性(上記の例ではattr要素のtrouble="MISSING")が無視される。

また、子要素や属性のあるXMLの場合、配列の中まで再帰的にキャストしていないのでSimpleXMLElementのままになってしまう。
$xml = '<?xml version="1.0" ?>
<root>
<parent>
<child>MUSUKO</child>
</parent>
<attr foo="FOO" bar="BAR" />
</root>';

$sx = simplexml_load_string($xml);

var_dump((array)$sx);

array(2) {
  ["parent"]=>
  object(SimpleXMLElement)#3 (1) {
    ["child"]=>
    string(6) "MUSUKO"
  }
  ["attr"]=>
  object(SimpleXMLElement)#2 (1) {
    ["@attributes"]=>
    array(2) {
      ["foo"]=>
      string(3) "FOO"
      ["bar"]=>
      string(3) "BAR"
    }
  }
}




これに対して、PHPマニュアルのコメント欄に一発で配列に変換する方法が書いてあった。
$xml = '<?xml version="1.0" ?>
<root>
<parent>
<child>MUSUKO</child>
</parent>
<attr foo="FOO" bar="BAR" />
</root>';

$sx = simplexml_load_string($xml);

var_dump(json_decode(json_encode($sx), true));

array(2) {
  ["parent"]=>
  array(1) {
    ["child"]=>
    string(6) "MUSUKO"
  }
  ["attr"]=>
  array(1) {
    ["@attributes"]=>
    array(2) {
      ["foo"]=>
      string(3) "FOO"
      ["bar"]=>
      string(3) "BAR"
    }
  }
}



json_decode()の第2引数(戻り値を連想配列にするかどうか)をtrueにするのがポイント。
属性は@attributesというKEYの連想配列に格納される。


しかし、属性とテキストノードの両方がある要素の属性が無視される問題は、このjson_encode/json_decodeを使った方法でも発症する。
$xml = '<?xml version="1.0" ?>
<root>
<attr trouble="MISSING">WHY?</attr>
</root>';

$sx = simplexml_load_string($xml);

var_dump(json_decode(json_encode($sx), true));

array(1) {
  ["attr"]=>
  string(4) "WHY?"
}

Why?
まあでも属性値がないことが分かっているXMLならこれで使えそう。(後から属性値を使いたいということになったら大変だけど。)

きちんとやりたいなら、SimpleXMLで取得したオブジェクトを属性も含めて配列に変換 | とりさんのソフト屋さんのやり方がスマートで良さそう。

2011年3月18日金曜日

AWS CloudFormationで PHP Hello World Applicationを作成してみた

AWS(Amazon Web Services)のCloudFormationの「PHP Hello World Application」に関する情報があまりないので試してみた。


まずはAWS Management Consoleから「PHP Hello World Application + SSH enabled」のstackを作成。
場所はAsia/Pacific 東京リージョンを選択できた。
インスタンスタイプはMicroインスタンス、OperatorEmailには自分のメールアドレスを記入した。


しばらくすると、こんなのが作成された。

  • S3
    • 空のバケットが作成された(バックアップ用?)
  • EC2
    • Root Device Typeがebsのインスタンスが1つ作成された
    • EBSのCapacityは8GiB
    • Security Groupが1つ作成された
      • SSHとHTTP(ポート番号は8888)のポートで、ともにIPアドレス制限無し
    • Load Balancerが起動した
      • 80番ポートを待ち受けてインスタンスの8888番ポートに向ける
    • Elastic IPは作成されなかった
  • CloudWatch
    • Alarmが3つ作成された
      • RequestLatencyAlarmHigh
      • CPUAlarmHigh
      • TooManyUnhealthyHostsAlarm
    • 閾値に達したら登録したメールアドレスにメールで知らせてくれるようだ
  • CloudFormation
    • stackが1つ作成された(そりゃそうだ)
  • RDS
    • DB Instanceが1つ作成された
      • DB Engine Versionは5.1.50
      • DB Instance Classはdb.m1.small
      • DB Storageは5GiB
      • Backup Windowは15:00~15:30(日本時間?)
      • Maintenance Windowは日曜14:00~14:30(これも日本時間?)
    • DB Security Groupが1つ作成された
      • 上記のEC2 Security Groupが適用されている
    • DB Parameter Groupのcharacter_set関連は「engine-default」になっているが、UTF-8使えるのかな?
  • SNS
    • CloudWatchのメール通知用のTopicが1つ作成された


EC2のLoadBalancerのドメインにHTTPでアクセスすると、Wellcomeメッセージとともにphpinfoが表示された。
phpinfoによるとバージョンは下記の通り。
  • Apache : 2.2.16
  • PHP : 5.3.3

SSHでアクセス(SSHのログインユーザーはrootでなく"ec2-user"なので注意。"ec2-user"はsudoができる)してみると、/var/www/html の中には index.php しかなかった。
ユーザー"ec2-user"のviはPHPのソースがハイライトされて見やすい。(少し目がチカチカするが。)

PHP拡張については主なものは入っているが、mbstringが入っていない。
yumで入れたら普通にインストールできた。
sudo yum install php-mbstring

mbstringを有効にするためにApacheを再起動。
すると、アクセスできなくなった。EC2のLoadBalancerからインスタンスが外れている。
SNSからのアラートメールもいくつも送られてきてる。

調べてみると、httpd.confでポート番号が80になっていた
8888に変更して再起動。

これでアクセスできるようになった。mbstringも使えるようになった。


使い終わったら、AWS Management ConsoleでCloudFormationのstackを削除。
するとCloudFormationが作った一連のものをきれいに削除してくれた。
例外はS3で、S3だけはバケットが残っていた。


あとこれは今回の調査に直接関係ないが、AWS Management ConsoleのS3とEC2が重くなった気がする。(この前の改善の影響?)


結論
ささっとPHP実行環境を作りたいなら、これもありかもしれないと思った。
RDSを使いたいかどうかは状況によるけど、CloudWatchとかSNSの設定が楽なのは便利そう。

2011年3月17日木曜日

Webブラウザからコーディングができるオンラインテキストエディタいろいろ




Webブラウザを使ってサーバ上のソースコード(テキストファイル)を編集できる、Webベースのオンラインテキストエディタを調べたメモ。
(さらっとしか調べてないので勘違い等あるかも。)



今のところ、本命はCloud9 IDEで、それをEclipse Orionが追う形か。(Orionがリリースされたらいろんな状況が一変するかも?)
でもPHPだけならecoderでいいかな?grepができない以外は基本的なことはできそう。
ちなみに、ecoderを試しに使ってみたら良かったので、結局他のは調べただけで試してはいない。


参考

2011年3月7日月曜日

Amazon EC2 東京リージョンと他のリージョンの価格比較


AWSの東京データセンターが開業したので、主な価格を他のリージョンと比較してみる。


US West
Asia Pacific
シンガポール
Asia Pacific
東京
EC2 Micro$0.025/時$0.025/時$0.027/時
EC2 Small$0.095/時$0.095/時$0.10/時
EC2 Medium$0.19/時$0.19/時$0.20/時
EBS$0.11/GB/月$0.11/GB/月$0.12/GB/月
S3(1TB以下)$0.154/GB/月$0.140/GB/月$0.150/GB/月


EC2は5%くらい高め、逆にS3はUS Westより安い。

速度(レイテンシ)は間違いなく東京が速いみたい。(参考:Amazon Web Servicesが日本に上陸!というわけで早速レイテンシやスループットを測ってみた - RX-7乗りの適当な日々


参考:AWSが日本データセンターを運用開始、責任者に聞いた - @IT

2011年3月3日木曜日

PHPの SJISと SJIS-WINの違い


SJIS-WINとは?

PHPで文字コードとして「SJIS-WIN」を指定すると、Microsoftが拡張したShift_JISであるWindows-31Jが使われる。

Windows-31Jは、Microsoftが「JIS X 0208-1990」をベースに、NECとIBMの独自拡張文字の一部(一般的にはSJISの「機種依存文字」と呼ばれる?)を取り込んだ文字コード。
(参考:Microsoftコードページ932 - Wikipedia



SJISとSJIS-WINで何が違うの?


SJIS-WINの方が文字が多い。

よく使うところでは、下記のような文字はSJISーWINにはあるがSJISにはない。

  • 丸数字 (①②③...⑳)
  • ローマ数字 (ⅠⅡⅢ...Ⅹ、ⅰⅱⅲ...ⅹ)
  • カッコ付きの株 (㈱)
  • はしご高[はしごたか] (髙)
  • たつ崎[たつさき、たちさき] (﨑)



SJIS-WINにはあるがSJISにはない文字

下記の3種類
  • NEC 特殊文字(13区)
  • NEC 選定 IBM 拡張文字(89~92区)
  • IBM 拡張文字(115~119区)

具体的な文字の一覧については下記参考サイトを参照。



SJIS-WINにはあるがSJISにはない文字を正規表現で探すには?

preg_match()等のPCRE関数はUTF-8以外のマルチバイト文字に対応していないので、そのままではShift_JISには使えない。(UTF-8の場合はパターン修飾子として"u"を付ければ使える。)
一見Shift_JISでも使えそうに見えることもあるが、Shift_JISの2バイト目と次の文字の1バイト目を1つの文字とみなしてヒットしてしまう場合がある。
preg_match('/[\x87][\x40-\x8F]/', 'ョ@'); // => true

対策としては、対象文字列をmb_substr()等を使いあらかじめ1文字ずつに分解しておいて、それを1文字ずつチェックしていけば正しく判定できる。

また、PHP4ではmb_ereg系の関数をこれに使えたみたいだが、鬼車のPHP5では使えないみたい。

単純にSJIS-WINにはあるがSJISにはない文字を含んでいるかどうかを判定しただけなら、それぞれの文字コードに変換した後に比較すれば分かる。
$utf8 = '株';
$sjis = mb_convert_encoding($utf8, 'SJIS', 'UTF-8');
$sjisWin = mb_convert_encoding($utf8, 'SJIS-WIN', 'UTF-8');

var_dump($sjis === $sjisWin); // => true

$utf8 = '㈱';
$sjis = mb_convert_encoding($utf8, 'SJIS', 'UTF-8');
$sjisWin = mb_convert_encoding($utf8, 'SJIS-WIN', 'UTF-8');

var_dump($sjis === $sjisWin); // => false

ブログ アーカイブ

tags