12

BankOne形式でトランザクションレコードをエクスポートできるはずのモジュールを作成しています。

フォーマットの仕様はこちらです

これがサンプルファイルです

フィールドは行の特定の範囲に配置され、レコードは新しい行で区切られます。フィールドが行の特定のポイントで開始および終了するようにするには、多くのスペースを追加する必要があります。

このためにphpで関数を書きました。フィールドをパラメーターとして受け取り、適切にフォーマットされたレコードを返す必要があります。

function record4($checknum='', $nameid='', $purpose='', $pledge='', $payment='', 
             $frequency='', $title='', $fname='', $lname='', $suffix='',
             $address='', $postalcode='', $city='', $state='', $greeting='')
{
$fields = array(
    'checknum' => array('length' => 8, 'start' => 37),
    'nameid' => array('length' => 7, 'start' => 45),
    'purpose' => array('length' => 5, 'start' => 52),
    'pledge' => array('length' => 10, 'start' => 57),
    'payment' => array('length' => 10, 'start' => 67),
    'frequency' => array('length' => 1, 'start' => 77),
    'title' => array('length' => 20, 'start' => 78),
    'fname' => array('length' => 40, 'start' => 98),
    'lname' => array('length' => 40, 'start' => 138),
    'suffix' => array('length' => 20, 'start' => 178),
    'address' => array('length' => 35, 'start' => 198),
    'postalcode' => array('length' => 10, 'start' => 233),
    'city' => array('length' => 28, 'start' => 243),
    'state' => array('length' => 5, 'start' => 271),
    'greeting' => array('length' => 40, 'start' => 276)
);

$str = '4';
foreach($fields as $field_name => $field)
{
    if($$field_name)
    {
        $str = str_pad($str, $field['start']-1, ' ');
        $str = $str.substr(trim((string)$$field_name), 0, $field['length']);
    }
}

return $str."\n";
}

意図したとおりに機能しているようですが、出力ファイルを見ると、次のことがわかりました(最後までスクロールしてください)。

4                                                                 1                              David                                   Landrum
4                                                                 3                              Hazel                                   Baker
4                                                                 3                              Jerome                                  Zehnder
4                                                                 1                              Víctor                               Nadales
4                                                                 2                              Philip                                  Nauert
4                                                                 1                              Jana                                    Ortcutter

このファイルには、データベースから取得した900個のレコードが含まれており、VÃctorNadalesを除いて、すべて正しくフォーマットされています。その名の後に、他のすべてのフィールドは、本来あるべき場所から3スペース残っています。このレコードの唯一の異常な点は、名の「Ã」であるように見えます。

この関数は、処理するすべてのフィールドの後に文字列を適切な長さにパディングすることになっていますが、どういうわけかこの1行でだまされますか?

ここで何が起こっているのか誰か教えてもらえますか?

編集:この形式のインポートファイルは、特別なUTF-8文字をサポートしていない可能性があることに気づきました。したがって、次の行をコードに追加しました。

$$field_name = iconv('UTF-8', 'ASCII//TRANSLIT', $$field_name);

Ãは次のように表示されます:〜A-。理想的ではありませんが、少なくともファイルは正しくフォーマットされています。

4

3 に答える 3

14

これは'Ã'、 がマルチバイト文字 (長さ 4 バイト) でありstr_pad、論理文字ではなくバイト数をカウントしているために発生しています。

これが、3 つのスペースが欠落している理由であり、1 つのマルチバイト文字ではなく 4 つのシングルバイト文字としてstr_padカウントされます。'Ã'

この機能を試してください (クレジットはこちら)。

<?
function mb_str_pad( $input, $pad_length, $pad_string = ' ', $pad_type = STR_PAD_RIGHT)
{
    $diff = strlen( $input ) - mb_strlen( $input );
    return str_pad( $input, $pad_length + $diff, $pad_string, $pad_type );
}
?>
于 2012-08-08T19:40:32.860 に答える
2
function mb_str_pad($input, $pad_length, $pad_string = ' ', $pad_type = STR_PAD_RIGHT) {
    $diff = strlen($input) - mb_strlen($input,mb_detect_encoding($input));
    return str_pad($input, $pad_length + $diff, $pad_string, $pad_type);
}
于 2014-01-07T09:40:05.627 に答える