Learn or Die

生涯勉強。Macです。

TCPDFのOutputで日本語ファイル名が消える

下記のように日本語でファイルを保存しようとすると、日本語部分が消えてしまいます。

<?php

$name = 'テスト ハナコ';
$pdf->Output($name.".pdf","I");

解決方法

tcpdfフォルダ直下のtcpdf.phpを修正する。
7592行目にあるOutputメソッド内の、下のpreg_replaceをコメントアウトする。

<?php

if ($dest[0] != 'F') {
    $name = preg_replace('/[\s]+/', '_', $name);
//  $name = preg_replace('/[^a-zA-Z0-9_\.-]/', '', $name);
}

7666行目のbasename関数を外す。

<?php

// 修正前
//header('Content-Disposition: inline; filename="'.basename($name).'"');
// 修正後
header('Content-Disposition: inline; filename="'.$name.'"');

これで日本語ファイルとして出力されました。

JOIN / LEFT JOIN / RIGHT JOINについて

JOIN

JOINは「内部結合」。
一番使用機会が多い。INNNER JOINの別名。
共通のカラムを条件に、複数テーブルの結合を行うことができる。 結合できなかった行は返さない。

LEFT JOIN / RIGHT JOIN

どちらも「外部結合」。
結合できなかった行があっても表示するので、一部レコードがNULLになる場合もある。
LEFTの場合は左側、つまりFROMで指定した側のテーブルを指し、そのテーブル側を軸に情報を表示する。

参考サイト

www.sejuku.net

qiita.com

IN演算子

IN演算子とは

WHERE 句で条件を指定するときに、 IN 演算子を使用するとカラムの中に、IN演算子で指定した値が存在するかどうか調べることができる。 マッチした場合は条件式はTRUEになる。

SELECT col_name FROM table_name
WHERE col_name IN (value1, value2, ...);

NOT IN演算子

IN 演算子の前に NOT を付けることでリストの中のどの値とも一致しない場合に条件式が TRUE となる。

SELECT col_name FROM table_name
WHERE col_name NOT IN (value1, value2, ...);

参考サイト

www.dbonline.jp

revertを取り消す

リモートのベースブランチでreveertし、消えてしまった修正分を再度pushする。

# ベースブランチに移動
$ git checkout master
# リモートの変更分を取り込む
$ git pull origin master
# 作業ブランチに移動
$ git checkout feature/task10
# ベースブランチの変更を取り込む
$ git merge master
# コミット履歴を確認
$ git log
# revertを取り消す。(つまりrevertをrevertする)
$ git revert <コミットID>
# 反映されているか確認後、リモートにpushする
$ git push origin feature/task10

Git – revert

revertとは

既存のコミットを取り消すためのコマンド。
「取り消したいコミットを打ち消すようなコミットを新しく作成する」という処理によって、既存のコミットを取り消す。
新しくコミットを追加しているだけなので、既存コミットの履歴が消えるわけではない。

resetとの違い

「既存のコミットを元に戻す」という点について、同じような機能を持つコマンドがreset。
revertコマンドは特定のコミットを元に戻すことができる。
resetコマンドは、「コミットを取り消した」というコミットが残らない。

使用方法

# コミット履歴を確認
$git log
# 指定のコミットを取り消す
$ git revert <コミットID>

qiita.com

サブクエリを使用した更新でエラー

エラー

update contract set contract_date = (select contract _date from contract where status = 8) where course_id > 1000;

上記のクエリを実行すると以下のエラーが発生。
You can't specify target table 'contract' for update in FROM clause

原因

mysqlでは更新対象テーブルとサブクエリのテーブルが一緒なのはダメ。

対処方法

サブクエリ部分にエイリアスをつけたり、結合条件としての使用であれば動く。

update contract target
    inner join (select * from contract where status = 8) prev 
    on target.old_contract_id = prev.new_contract_id 
    set target.contract_date = prev.contract_date
    where target.course_id > 1000;

参考サイト

qiita.com

Eloquentのsaveとupdateは処理が異なる

saveとupdateのちがい

update()は更新データとの差分を見ずに更新する。
save()は更新データとの差分を見て更新するかを決める。

例)Customerテーブルのnameを更新する
update()を使用した場合

<?php

Customer::where('id', 1)
          ->update(['name' => $request->name]);

save()を使用した場合

<?php

$customer = Customer::find(1)
$customer->name = $request->name;
$customer->save();

もし$request->nameが既存データと同じだった場合、
save()→updated_atが更新されない
update()→updated_atが更新される

vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.phpのsaveメソッドを確認すると、データが存在している場合のみ、updateが実行されていることがわかる。