PHPのfile関数でcsvを読み込んだ時に改行コードが含まれていた
下記のようなcsvファイルを読み込んでweb上に表示させる画面を作りました
20170410,タイトル1 20170411,タイトル2 20170412,タイトル3 20170413,タイトル4 20170414,タイトル5
まずfile関数で1行ずつ配列に格納しました
<?php $array = file("/history.csv"); // $array[0]は"20170410,タイトル1" // $array[1]は"20170411,タイトル2" ?>
後はこの配列をループさせて画面に表示するだけ
<?php $array = file("/history.csv"); $content .= "<ul>"; for($i = 0;$i < count($array);$i++){ $str = split(",", $array[$i]); $dt = date('Y/m/d', strtotime($str[0])); $content .= "<li>".$dt." ".$str[1]."</li>"; } $content .= "</ul>"; echo $content; ?>
画面で表示した結果
2017/04/10 タイトル1 2017/04/11 タイトル2 2017/04/12 タイトル3 2017/04/13 タイトル4 2017/04/14 タイトル5
ここまではよかったのですが、この配列にデータを追加してその内容でcsvファイルを更新ようとした時問題が発生しました。
<?php $array = file("/history.csv"); array_push($array, "20170415,タイトル6"); $file = fopen("/history.csv", "w"); for($i = 0;$i < count($array);$i++){ @fwrite($file, $array[$i]."\r\n"); } fclose($file); ?>
出力したcsvファイル
2017/04/10 タイトル1 2017/04/11 タイトル2 2017/04/12 タイトル3 2017/04/13 タイトル4 2017/04/14 タイトル5 2017/04/15 タイトル6
何故か改行が増えてる・・・
改行コードは1個だけしか付加してないのに
原因はfile関数でcsvファイルを読み込む時に改行コードまで読み込んでいたから
読み込んだ時に下記のようになっていたということです
<?php $array = file("/history.csv"); // $array[0]は"20170410,タイトル1\r\r" // $array[1]は"20170411,タイトル2\r\r" ?>
file関数オプションにFILE_IGNORE_NEW_LINESを追加することで改行コードは付加されずに読み込まれます
<?php $array = file("/history.csv", FILE_IGNORE_NEW_LINES); // $array[0]は"20170410,タイトル1" // $array[1]は"20170411,タイトル2" ?>
修正後に出力したcsvファイル
2017/04/10 タイトル1 2017/04/11 タイトル2 2017/04/12 タイトル3 2017/04/13 タイトル4 2017/04/14 タイトル5 2017/04/15 タイトル6
正規表現で特定の文字列を含まない行、含む行を抽出
先日とある会社のシステムのリリースがありました。
かなり大規模なシステムなので予想通りリリース後
いろいろと問題が発生し、ログ解析する日々です。
ログのフォーマット
2017/03/22 12:00:03 INFO START testAction1.do 2017/03/22 12:00:06 INFO END testAction1.do 2017/03/22 12:00:08 INFO START xxxAction2.do 2017/03/22 12:00:10 FATAL java.lang.NullPointerException ・ ・ ・ javax.servlet.http.HttpServlet.service(HttpServlet.java:617) javax.servlet.http.HttpServlet.service(HttpServlet.java:717) ・ ・ ・ 2017/03/22 12:03:08 INFO START xxxAction3.do 2017/03/22 12:00:10 WARN xxx.ValidateException ・ ・ ・ javax.servlet.http.HttpServlet.service(HttpServlet.java:617) javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
Javaで構築されたシステムで、予期しない例外が発生するとログに内容が出力されます。
ログから"Exception"を含む行を秀丸エディタでgrepして目的の行を検索するのですが、使用しているフレームワークが出力する例外(ValidateException)が大量に出力されて数千件ヒットしてしまいます。
そこで正規表現を使って"Exception"を含む行かつ
"ValidateException"を含まない行を抽出できるようにしました
^(?!.*ValidateException).*(?=Exception).*$
^(?!.*ValidateException).*$で"ValidateException"を含まない行がマッチします。
そこに(?=Exception)を合わせることによって
"ValidateException"を含まない行、
かつ"Exception"を含む行がマッチします。
これで検索結果がかなり絞られましたが、他にもチェック不要な例外(TimeOutException)が
あることが判明
この例外も除外したいので"ValidateException"と"TimeOutException"を含まない行に条件を変更しました
^(?!.*(ValidateException|TimeOutException)).*(?=Exception).*$
除外したい文字列を()で囲んで|で区切るだけです。
これでログ解析の効率がかなりアップしましたよ。
HTTP_USER_AGENTを利用してcssを切り替える
PC用のcssとスマホ用のcssを用意してデバイスによって読み込むcssを切り替えたいと思います。
最初に考えたのがlink要素の「media」属性を利用すること
メディアクエリというやつです
PC用
<link rel="stylesheet" type="text/css" media="screen and (min-width:901px)" href="css/style_pc.css"/>
画面サイズが901px以上の場合、style_pc.cssを読み込みます
スマホ用
<link rel="stylesheet" type="text/css" media="screen and (max-width:900px)" href="css/style_smp.css"/>
画面サイズが900px以下の場合、style_smp.cssを読み込みます
しかし、この方法だと画面サイズが判断されるのでPCで画面サイズを小さくした場合style_smp.cssを読み込んでしまいます
最近はスマホでも画面サイズが大きいのでスマホがstyle_pc.cssを読み込む可能性もあります
そこでユーザーエージェントを利用してcssを切り替えることにしました
<?php $ua=$_SERVER['HTTP_USER_AGENT']; $isSmp = ((strpos($ua,'iPhone')!==false)|| (strpos($ua,'iPad')!==false)|| (strpos($ua,'Android')!==false)); ?>
$_SERVER['HTTP_USER_AGENT']でユーザが利用しているOS情報等が取得できます
strposでユーザーエージェントにiPhone、iPad、Androidという文字列が存在するかチェックし
存在すればスマホと判断します
<?php if ($isSmp) {?> <link rel="stylesheet" type="text/css" href="/css/style_smp.css" /> <?php } else {?> <link rel="stylesheet" type="text/css" href="/css/style_pc.css" /> <?php }?>
$isSmpの値でスマホかどうか判別し読み込むcssを切り替えます
この状態でmax-device-withやmax-with等使ってスマホ用のレイアウトを
スマホとタブレットに切り替えたりPC用のレイアウトを解像度が低いPCと高いPCに
切り替えたりするのもいいかなと思ってます
viewportを指定してスマホでも見やすくする
勉強も兼ねて構築中のサイトをスマホでみると非常にみにくい
何故ならPC用のサイトしか用意していないから
PC用のサイトが9割ほど完成したのでスマホ用のデザインもぼちぼち考えていきます
PC用のサイトをスマホでみるとみにくい原因はというと、
スマホがPC用のサイトを表示する時は横幅が980pxで表示しようとするかららしいです
自分のスマホの横幅をscreen.widthで取得すると360pxでした
そこに横幅980pxのレイアウトを合わせようとするので縮小されて表示されます
PCサイトをスマホで表示
対策は横幅980pxで表示しようとするのを360pxにすればよいです
そのためにはviewpointを指定します
<meta name="viewport" content="width=device-width;" />
viewport指定後のPCサイトをスマホで表示
device-widthでスマホの横幅に合うようになり縮小されずに表示されました
しかし横向きにすると横幅が広がるため拡大してします
スマホを横向きにして表示
viewportの記述を下記にすることで横向きにしても拡大されません
<meta name="viewport" content="width=device-width, initial-scale=1.0,minimum-scale=1.0, maximum-scale=1.0,user-scalable=no">
viewportを変更して表示
拡大されずに表示されました
ただし、この指定をするとピンチによる拡大縮小ができません
個人的には拡大縮小できなくてもいいと思ってるのでこの設定をベースにスマホ用のcssを作成してPCとスマホのデザインを切り分けていきたいと思ってます