SJISの機種依存文字をUTF-8に正常に変換する

mb_convert_encoding()もしくはmb_convert_variables()でSJISSJIS-WIN→UTF-8の順に変換すると、機種依存文字が?にならずに正常変換できる。

最近Webスクレイピングして、その画面のデータを集計するみたいなことばっかりやっているんですが(DBアクセス権限貰えないんで)、この時webページをSJISで一旦保存して、テキストを解析するような段階を踏むプロウラムを書いてました。
その時に機種依存文字が使われていると、UTF-8に変換した時に機種依存文字が文字化けして、うまくデータベースに保存できないということが起きて、今までなんとなく適当に変換してうまくいったらそれでスルーしてた問題を、ちゃんと解決させようと思って色々調べてみました。
どうやら、"SJIS"から"UTF-8"に直接変換するとダメで、"SJIS-WIN"という文字コードなら、、"SJIS"からの変換も正常に行えて、"SJIS-WIN"から"UTF-8"に変換しても文字化けせずにいけるということがわかりました。

PHP】【機種依存文字】Shift-JIS→utf-8文字コード変換時に機種依存文字が文字化け | ぷしゆのWEBクリ道場
http://ameblo.jp/pushurinko/entry-10188981645.html

PHPで、いわゆる機種依存文字文字コード変換(EUC-JP→UTF-8)にはまる | エンジニアが作る最新ITブログ
http://www.asp-edita.jp/doda/one/doda5728_15.html

[PHP] mb_ereg()じゃない、preg_match_all()に/uをつけるんだ! | ネットサービス運営日誌
http://ifs.seesaa.net/article/26300967.html


そんなわけで、

<?php
//実行ファイルはUTF-8。ロードするファイルがSJIS
$val = file_get_contents('sjis.txt');
mb_convert_variables('SJIS-WIN', 'SJIS', $val);
mb_convert_variables('UTF-8', 'SJIS-WIN', $val);
echo $val;
?>

これで変な感じにならずに期待した値を得られます。