サンプル・プログラムの実行例
サンプル・プログラム
isbn2asin.php | サンプル・プログラム本体。 |
pahooInputData.php | データ入力に関わる関数群。 使い方は「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。 |
バージョン | 更新日 | 内容 |
---|---|---|
1.5.0 | 2023/10/01 | pahooInputData導入 |
1.4 | 2021/05/03 | PHP8対応,リファラチェック追加 |
1.3 | 2016/06/04 | ハイフン無視,Amazon商品リンク |
1.2 | 2015/09/20 | bug-fix |
1.1 | 2010/05/18 | bug-fix |
バージョン | 更新日 | 内容 |
---|---|---|
1.5.0 | 2024/01/28 | exitIfExceedVersion() 追加 |
1.4.2 | 2024/01/28 | exitIfLessVersion() メッセージ修正 |
1.4.1 | 2023/09/30 | コメントの訂正 |
1.4.0 | 2023/09/09 | $_GET, $_POST参照をfilter_input()関数に置換 |
1.3.0 | 2023/07/11 | roundFloat() 追加 |
ISBNコード
2006年(平成18年)12月31日までは10進数10桁の番号が用いられていたが、2007年(平成19年)以降には10進数13桁の番号へ移行した。ここでは現行規格を中心に説明する。
ISBNコードは10進数13桁からなり、その内容は下記の通りである。
桁 | 内容 |
---|---|
13-11 | 識別番号(978または979) |
10 | グループ記号(出版国などを表す数字で、日本は4) |
9-6 | 出版者記号 |
5-2 | 書名記号 |
1 | チェックデジット |
内容 | 値 |
---|---|
識別番号 | 978 |
グループ記号 | 4 |
出版者記号 | 8443 |
書名記号 | 2788 |
チェックデジット | 2 |
チェックデジットはモジュラス10 ウェイト3 という方式である。以下のように計算する。
- チェックデジットをのぞく一番左側の桁から順に1,3,1,3を掛けて、それらの和を取る。
- 和を10で割った余りを10から引く。ただし10で割って出た余りの下1桁が0の場合は0とする。
9×1+7×3+8×1+4×3+8×1+4×3+4×1+3×3+2×1+7×3+8×1+8×3=138となり、チェックデジットの 2 を得ることができる。
138%10=8
10-8=2
ちなみに、旧規格(2007年12月31日まで)は10進数10桁であるが、グループ記号、出版者記号、書名記号は現行規格と同じである。チェックデジットの計算方法は異なる(モジュラス11 ウェイト10-2)。
ASINコード
ISBNの現行規格についても、識別番号が978であるものについては、桁数10-2は同一である。ただしチェックデジットの計算方法がモジュラス11 ウェイト10-2であるため、最後の1桁の数字が異なる。
モジュラス11 ウェイト10-2方式は、以下のように計算する。
- チェックデジットを除いた左側の桁から10,9,8‥‥2を掛けてそれらの和を取る。
- 和を11で割って出た余りを11から引く。
4×10+8×9+4×8+4×7+3×6+2×5+7×4+8×3+8×2=268となり、チェックデジットの 7 を得ることができる。
268%11=4
11-4=7
ISBNとASINの関係
解説:ISBNコードをASINコードに変換する
151: /**
152: * ISBNコードをASINコードに変換する
153: * @param string $isbn ISBNコード(10進数10桁 or 13桁)
154: * @return string ASINコード(10進数10桁)/FALSE:変換に失敗
155: */
156: function isbn2asin($isbn) {
157: //旧ISBNコードの場合はそのまま返す
158: if (preg_match('/^[0-9]{9}[0-9X]$/', $isbn) == 1) {
159: if (cd11($isbn) != substr($isbn, 9, 1)) return FALSE;
160: return $isbn;
161: }
162:
163: //入力値チェック
164: if (preg_match('/^[0-9]{13}$/', $isbn) != 1) return FALSE;
165: if (cd10($isbn) != substr($isbn, 12, 1)) return FALSE;
166: if (preg_match('/^978/', $isbn) == 0) return FALSE;
167:
168: $code = substr($isbn, 3, 10); //10-1桁目を取り出す
169: $cd = cd11($code);
170:
171: return substr($isbn, 3, 9) . $cd;
172: }
118: /**
119: * チェックデジットの計算(モジュラス11 ウェイト10-2)ASIN用
120: * @param string $code 計算するコード(最下位桁がチェックデジット)
121: * @return int チェックデジット
122: */
123: function cd11($code) {
124: $cd = 0;
125: for ($pos = 10; $pos >= 2; $pos--) {
126: $n = substr($code, (10 - $pos), 1);
127: $cd += $n * $pos;
128: }
129: $cd = $cd % 11;
130: $cd = 11 - $cd;
131: if ($cd == 10) $cd = 'X';
132: if ($cd == 11) $cd = '0';
133: return $cd;
134: }
136: /**
137: * チェックデジットの計算(モジュラス10 ウェイト3)
138: * @param string $code 計算するコード(最下位桁がチェックデジット)
139: * @return int チェックデジット
140: */
141: function cd10($code) {
142: $cd = 0;
143: for ($pos = 13; $pos >= 2; $pos--) {
144: $n = substr($code, (13 - $pos), 1);
145: $cd += $n * (($pos % 2) == 0 ? 3 : 1);
146: }
147: $cd = $cd % 10;
148: return ($cd == 0) ? 0 : 10 - $cd;
149: }
ただ、入力値のチェックは細かく行っている。
入力値が10進数10桁なら旧ISBNとして処理をする。この際、チェックデジットが合っているかどうか検査する。※10桁の末尾が 'X' の時に正常に動作しませんでした。クロメルさん、ご指摘及び改良方法の提案をありがとうございました(2015年9月20日)。
入力値が10進数13桁なら現行ISBNとして処理をする。この際、チェックデジットがあっているかどうか検査する。また、上位3桁が978以外の場合は変換処理ができないようにしてある。
チェックデジットの計算には、ユーザー関数 cd10, cd11 を用意した。
解説:メインプログラム
238: // メイン・プログラム ======================================================
239: //パラメータを取得する.
240: $res = $errmsg = '';
241: $isbn = getValidString('isbn', $errmsg, DEF_ISBN, 10, 20, TRUE, array('/^[0-9\-]+$/iu'));
242:
243: //ISBN→ASIN変換
244: if ($errmsg === '') {
245: $isbn2 = preg_replace('/\-/', '', $isbn); //ハイフンを除く
246: if (($asin = isbn2asin($isbn2)) === FALSE) {
247: $errmsg = "'{$isbn2}' は ISBN コードではありません.";
248: } else {
249: $res =<<< EOT
250: ASINコード {$asin}<br>
251: Amazon商品 <a href="https://www.amazon.co.jp/dp/{$asin}">https://www.amazon.co.jp/dp/{$asin}</a>
252:
253: EOT;
254: }
255: }
256:
257: //表示テキストを作成する.
258: $HtmlBody = makeCommonBody($isbn, $res, $errmsg);
259:
260: //画面に表示する.
261: echo $HtmlHeader;
262: echo $HtmlBody;
263: echo $HtmlFooter;
264:
265: /*
414: /**
415: * HTML FORMで指定したINPUTの内容を文字列として取り出す(バリデーション付き)
416: * filter_input()関数および $argv を参照する.
417: * @参考URL https://www.pahoo.org/e-soul/webtech/phpsec/phpsec-10-01.shtm
418: * @param string $key パラメータ名(省略不可)
419: * @param string $errmsg エラーメッセージを格納する(省略不可)
420: * @param mixed $def 初期値(省略時:空文字)
421: * @param int $minlen 入力可能な最小長(省略時=1)
422: * @param int $maxlen 入力可能な最大長(省略時=99)
423: * @param bool $exclusion $patternsはTRUE:受容/FALSE:排除(省略時=TRUE)
424: * @param array $patterns 受容/排除するパターンマッチ配列(省略時=NULL)
425: * @return string 入力値
426: */
427: function getValidString($key, &$errmsg, $def='', $minlen=1, $maxlen=99, $exclusion=TRUE, $patterns=NULL) {
428: $data = (string)getParam($key, TRUE, $def); //URLパラメータを取り出す
429: $str = trim($data); //先頭・末尾の空白文字を除く
430: $str = htmlspecialchars($str); //XSS対策
431: //文字列バリデーション
432: if ($str != '') {
433: $res = validString($data, $errmsg, $minlen, $maxlen, $exclusion, $patterns);
434: }
435:
436: return $str;
437: }
また、このプログラムはコマンドラインから単独で利用できるようにしてある。
isbn2asin.php?isbn=9784844327882のように実行すると、標準出力にASINコードのみが出力される。エラー発生時には 'ERROR' と出力する。
参考サイト
- 日本図書コード管理センター
- PHPでISBNコードからNDCコードを求める:ぱふぅ家のホームページ
- PHPで国立国会図書館を検索:ぱふぅ家のホームページ
- PHPで楽天ブックスAPIを使って書籍検索:ぱふぅ家のホームページ
今回は、PHPを使って、国際標準図書番号「ISBN」から、ASIN へコード変換するプログラムを作ってみることにする。
(2023年9月30日)pahooInputData導入