1万件のCSVを読み込みテーブルに保存する雛形コード #PHPCode

2022.09.08

Logging

おはようございます、徐々に秋ぽっい日差しになってきましたね(まだ暑いけども😌)。

今日は、1万件のCSVを読み込みテーブルに保存する雛形コードを昨日、ちょちょっと書きましたので記載します。ファイルをダウンロードして使いたい方はGithubのリンクを下に貼っときますので、ご使用頂けたらと思います。尚、テーブルなどはCSVを参考にご自身で構えてください。

※動作環境はPHP8系です、なのでPHP7系では一部エラーが出ます。fgetcsv…nullを0へ変更。

Githubのリンクはこちら

Qiitaの方に記載しようかどうしようか、迷ったのですが第一弾目がアクセス数がそこそこ伸びたのでこれ以上、注目されるのは嫌なのでブログの方に記載しました。1万件のCSVを簡単に読み込ませる方法はPHPコードを書くのではなく、SQLのコマンドで実行した方が実は早いですけど・・・。

https://twitter.com/taoka_toshiaki/status/1567489169919975424
有言実行

早いですけど、その場合、CSVがちゃんとしたファイルではないと上手くテーブルに保存されない場合や、そもそもコマンドラインで操作出来ない場合もあったりしてPHPコードなどで制御しないと駄目な事もあります。そんな時に、このコードをサンプルとして使って頂ければ良いなと思い作りました。

1万件のCSVを読み込ませるPHPコード雛形。

そんなにコードを書かなくてもまぁ動くんですよ。ちなみにソースコードには、あまりコメントを書いていないですが、プログラマーなら大体の人が理解できるレベルかと思います。

<?php
//ini_set("display_errors","On");
session_start();
require "db_config.php";

//読み込みCSVファイル名セット
class csv
{
    /**
     * @param string $filename
     * @param int $cnt
     * @return Object
     */
    public function ini_csv($filename = "", $cnt = 0)
    {
        return new csv_read($filename, $cnt);
    }
}

//CSVデータを読み込ます
class csv_read
{
    var $max = 10000;
    var $cnt = 0;
    var $handle = null;
    /**
     * @param string $filename
     * @param int $cnt
     */
    public function __construct($filename = "", $cnt = 0)
    {
        $this->cnt = $cnt;
        $this->handle =  fopen($filename, "r");
        $_SESSION["offset"] ? fseek($this->handle, $_SESSION["offset"]) : $this->handle;
    }
    /**
     * @param int $header_skip
     * @return Object
     */
    public function reader($header_skip = 0)
    {
        if ($this->handle !== FALSE) {
            $response = null;
            $data = fgetcsv($this->handle, null, ",");
            if (!$header_skip || $_SESSION["offset"]) {
                if ($data !== FALSE) {
                    $_SESSION["offset"] = ftell($this->handle);
                    $response["data"] = $data;
                    $response["cnt"] = $this->cnt > $this->max ? 0 : ($this->cnt + 1);
                    $flag = true;
                } else {
                    $_SESSION["offset"] = null;
                    $flag = false;
                }
            } else {
                $_SESSION["offset"] = ftell($this->handle);
                $response["cnt"] = $this->cnt > $this->max ? 0 : ($this->cnt + 1);
                $flag = false;
            }
        } else {
            $_SESSION["offset"] = null;
            $flag = false;
        }
        return new table_save($flag, $response);
    }
}

//tableにCSVデータを保存
class table_save
{
    var $flag = false;
    var $result = null;
    /**
     * @param boolean $flag
     * @param array  $response
     * @return void
     */
    public function __construct($flag, $response)
    {
        $this->flag = $flag;
        $this->result = $response;
        $this->column_name = "name,,...";
    }
    /**
     * @param string  $column_name
     * @return void
     */
    public function tbl_save($column_name = "")
    {
        if ($this->flag) {
            $column = $column_name ? $column_name : $this->column_name;
            $is_column = explode(",", $column);
            foreach ($is_column as $key => $val) {
                $is_value[$val] = $this->result["data"][$key];
            }
            try {
                $pdo = new PDO(DSN, USERNAME, PASSWORD);
                $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                $sql = (function ($is_column) {
                    $INSERTFIRST = null;
                    $INSERTLAST = null;
                    foreach ($is_column as $key => $val) {
                        $INSERTFIRST[] = "$val";
                        $INSERTLAST[] = ":$val";
                    }
                    $INSERTSQL = "(" . implode(",", $INSERTFIRST) . ")values(" . implode(",", $INSERTLAST) . ")";
                    $UPDATESQL = null;
                    foreach ($is_column as $key => $val) {
                        $UPDATESQL[] = "$val = :$val";
                    }
                    return "INSERT INTO " . TABLENAME . $INSERTSQL . " ON DUPLICATE KEY UPDATE " . implode(",", $UPDATESQL) . ";";
                })($is_column);

                $stmt = $pdo->prepare($sql);
                foreach ($is_value as $key => &$value) {
                    $is_type = ($key === "test3" || $key === "test13") ? PDO::PARAM_INT : PDO::PARAM_STR;
                    $stmt->bindValue(":$key", $value, $is_type);
                }
                $this->result["sql"] = $stmt->execute();
            } catch (\Throwable $th) {
                //throw $th;
                $this->result = null;
                print $th->getMessage();
            }
        }
        print json_encode($this->result);
    }
}

//RUN...POST DATA
if (isset($_POST["csrf_token"])  && d_xss($_POST["csrf_token"]) === $_SESSION['csrf_token']) {

    $_SESSION["offset"] = (int)d_xss($_POST["reset_flag"]) === 1 ? null : d_xss($_SESSION["offset"]);
    $filename = d_xss($_POST["filename"]);
    $cnt = (int)d_xss($_POST["cnt"]);

    $column_name = "test1,test2,test3,test4,test5,test6,test7,test8,test9,test10,test11,test12,test13,test14,test15";
    $header_skip = 1;

    $csv = new csv();
    $csv->ini_csv($filename, $cnt)->reader($header_skip)->tbl_save($column_name);
    $csv = null;
} else {
    print "";
}
function d_xss($data){
    $data = strip_tags($data);
    $data = htmlspecialchars($data,ENT_QUOTES);
    return $data;
}
<?php
 // ログインした状態と同等にするためセッションを開始します
 session_start();
 // 暗号学的的に安全なランダムなバイナリを生成し、それを16進数に変換することでASCII文字列に変換します
  $toke_byte = openssl_random_pseudo_bytes(16);
  $csrf_token = bin2hex($toke_byte);
  // 生成したトークンをセッションに保存します
  $_SESSION['csrf_token'] = $csrf_token;
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="Description" content="Enter your description here"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
<title>CSV</title>
</head>
<body>
    <input type="hidden" name="csrf_token" value="<?=$csrf_token?>">
    <span class="h3" id="cnt"></span><br><br>
    <span class="h4" id="read_csv"></span><br><br>
    <span class="h4" id="debug"></span><br><br>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.1/umd/popper.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.0/js/bootstrap.min.js"></script>
<script>
    window.onload = function(){
        read_csv(0,1);
    };
    function read_csv(cnt,reset_flag){
        try{
            $.ajax({
            type: "post",
            url: "./assets/php/class_csv.php",
            async: false,
            data: {csrf_token:document.getElementsByName("csrf_token")[0].value,reset_flag:reset_flag,filename:"dummy.csv",cnt:cnt},
            dataType: "json",
            success: function (response) {
                    if(response){
                        cnt = response.cnt;
                        document.getElementById("cnt").innerText = cnt;
                        if(response.data){
                            document.getElementById("read_csv").innerText = response.data[0] + response.sql;
                            document.getElementById("debug").innerText = cnt ===21?response.data:document.getElementById("debug").innerText;
                        }
                        setTimeout(function(){read_csv(cnt)},0);
                    }
                }
            });
        }catch(e){
            console.warn(e);
            read_csv(cnt);
        }
    }
</script>
</body>
</html>

タグ

0, , 7, 8, CSV, fgetcsv, github, null, php, PHPCODE, qiita, SQL, アクセス, エラー, コード, こちら, コマンド, これ, ご使用, ご自身, ダウンロード, ちょ, テーブル, ファイル, ブログ, リンク, , 一部, , , 今日, 保存, 動作, 参考, 変更, 実行, , 方法, 日差し, 昨日, 有言実行, 注目, 環境, , 簡単, 記載, 雛形,

機械学習は学習するのにどれぐらいのデータが必要?

2022.09.06

Logging

今日は大荒れ☔との事です、おはようございます。

8月の半ばにとある事情で機械学習で人の顔かどうかを判別させるモデルをTensorFlowで作ってみたのですが、結果、学習のデータが少なかったのが原因なのか分からないけども・・・。人工無能と言いたくなるほど無能な機械学習が出来上がりました。犬の画像を見せてもこれは人ですと判定してくれるので正直、ホントげんなりでした。

画像分類の作り方は簡単です、学習したいディレクトリとテスト用のディレクトリを作り、それぞれの階層に分類ディレクトリを設置し、その中に学習の画像データとテスト用の画像データを入れてサンプルコードをちょちょっと修正してテンソル(Pythonを実行)で学習してもらうだけです。

画像分類器を作る(機械学習ゼーロからヒーローへ – 第4部)
画像分類器を作る(機械学習ゼーロからヒーローへ – 第4部)

尚、自分のテストデータは100枚ほどしかなかったので、全然駄目な結果になりましたが3000枚以上の画像データがあればちゃんとした判別が出来たのかも知れません。

スマホの顔認証は動画データを画像データー変換して学習させているのでしょうね。そうすれば数千枚の画像は生成出来ると思います。

例えばopencv-pythonなんかで画像変換するのが良さそうですよ。

pip install opencv-python

タグ

100, 3000, 4, 8, Python, tensorflow, コード, これ, サンプル, ゼーロ, それぞれ, ちょ, データ, ディレクトリ, テスト, テンソル, どれぐらい, ヒーロー, ホント, モデル, , , 事情, , 人工, 今日, 作り方, 修正, 分類, 判別, 判定, 半ば, 原因, , 大荒れ, 学習, 実行, 必要, 機械, 正直, 無能, , 画像, 簡単, 結果, 自分, 設置, 階層, , 駄目,

雇われてお金を稼ぐこととフリーでお金を稼ぐこと。

2022.06.20

Logging

おはよう御座います。今日は全国的に雨なのかな?円安大丈夫かな?

人のふんどしで相撲を取るってことわざを思い出したので。今日のお題である「雇われてお金を稼ぐこととフリーでお金を稼ぐこと」を書いていきます。最初に結論を書くと雇われるという生き方は大変だけどフリーランスで稼ぐよりかは幾分楽なんですよって話です。

今の職業に就く前はフリーで一年間ほど活動していました、正確に言うと就職活動を主にしてフリーランスはちょっちしていました。それでも一からお金を生み出すということは大変だと実感しました。やり甲斐はあると思いますが、突き通すには結構な覚悟が必要かなって思います。

雇われて生きていくのは、何だかんだで楽なんですよ。経営者やフリーは毎月のお金を生み出す仕組みやそれを維持していくなどが大変です。従業員が多くなるほどお給与もその分支払わないといけないし、光熱費や何やらも伸し掛かってくる訳ですからね、そして経営が傾く場合だってあるわけですからね。

なので、自分はフリーはオススメしません、余程、副業が上手く回っている人じゃないとその道に進まない方が良いです。

タグ

お金, こと, ことわざ, それ, ちょ, フリー, ふんどし, やり甲斐, ランス, , , 今日, 光熱, 円安, , , 場合, 大変, 実感, 就職, 従業, 必要, 最初, 正確, 毎月, 活動, 生き方, 相撲, 経営, 経営者, 結構, 結論, 給与, 維持, 職業, 覚悟, , , , ,

お金もないのに株を買う?

2021.03.16

Logging

お金もないのに株を買う、株を100株ほど買いました。どうなるか分かりませんが株を買いその利益で国民年金の1年分を相殺したいと考えています。この株を長期保有することは考えていません。どうなるか分からないと書きましたが利益はおそらく出るのではないかと考えていて、昨日の午前中に買いましたが今の所、1350円ほど利益は出てます。前年度の同じ時期と比べてみてもまぁ同じような動きをしているので、おそらく大丈夫だろうという考えのもとで買いました。売るタイミングも決まっています。プロのデイトレードの方はギリギリまで見極めようとするでしょうけど、自分はそんな力量はないのである期間保有して売ります。因みに相殺と記載していますが、コロナ禍なのでおそらく凄く利益が出ても10万円ぐらいだと思います。利益が悪ければ2?3万止まりだろうと考えています。

https://twitter.com/zip358com/status/1371602936300593152

因みに本日、デイトレードの電子書籍を買いました、デイトレードする人になるのかは読んでから判断します。この本、3000円ちょっとする本ですが電子書籍はいま期間限定のセールをしていて499円で買えちゃったので今ならお得感あります、3004ページあるので!

タグ

, 10, 100, 1350, 2, , 3000, お金, ギリギリ, こと, コロナ, タイミング, ちょ, ディ, トレード, プロ, もと, , , , 保有, 判断, 利益, 前年度, 力量, 午前, 国民年金, , , 昨日, 時期, 書籍, 期間, , 本日, , 相殺, , 自分, 記載, 長期, 電子,

映画、海賊とよばれた男を観に行ったのですが #映画レビュー

2016.12.10

Logging


映画、海賊とよばれた男を観に行ったのですが
どうしても感情移入出来なかった。
「いっちょやってやろうやないかい」「熱が足りん熱が!!」などの予告を見て
見てみたいなぁと思って観に行ったんだけど、
どうしても感情移入出来なかったのです、VFXの技術は
上がっているので、そこはかなり評価出来ると思います、
映像的には全然、違和感がないレベルに達していると思います。
そこは凄く今後の日本映画に希望とチャンスを与えてくれる作品に
なっていると思います。どうして感情移入が出来なかったのか、
一番の理由は戦争の描写です。何故か戦争を美化しているように思えて
仕方なかったのが原因かなと思います。
「永遠の0」の監督だからかな原作読んでいないので何とも言えない。
https://www.youtube.com/watch?v=03va5qDFyzY

タグ

VFX, かなり, チャンス, ちょ, 予告, 作品, 原作, 原因, 始末, 希望, 感情移入, 戦争, 技術, 日本映画, 映画レビュー, 海賊, , 理由, , , 違和感,

宇宙兄弟LIFT OFF!の感想なんかをイマゴロ。

2014.08.24

Logging

宇宙兄弟LIFT OFF!の感想なんかをイマゴロ書きたいと思います。俗に言うエンターテイメントに仕上がっている映画になっています。特にお気に入りはオープニングの映像かなと思ったりしてます。アレで結構、映画の中に引き込まれそうな、そんな感じのオープニングです。ちなみにCG技術はアメリカには劣る感じがします。若干、CGは見劣りするもののストーリー事態がしっかりしているので見やすいです。あと、原作の漫画のキャラクターと実写の配役が結構うまいと思います。
2014/08/24:宇宙兄弟#0が映画館で上映中です、ちょっち観たいような気がしますが、今のところ保留にしています。宇宙兄弟#0も実写映画化して欲しいトコロですけど予算的に無理だったからアニメ映画になったか、もしくは実写映画効果でさらにファンが付いたからアニメ映画でGOサインが出たのかも。{勝手な思い込み(^_^)です}。

タグ

0, 08, 2014, 24, Cg, go, LIFT, off, アニメ, アメリカ, アレ, いま, エンターテイメント, オープニング, お気に入り, キャラクター, ごろ, サイン, ストーリー, ちょ, ところ, トコロ, ファン, もの, 上映, , 事態, , 保留, 兄弟, 効果, 勝手, 原作, 宇宙, 実写, 感じ, 感想, 技術, 映像, 映画, 映画館, , 漫画, 若干, 見劣り, 配役,