使いやすいUIとは?

8月に入って暑い日が続いています。脱水には気を付けなければ・・・と思いつつコーヒーばかり飲んでいます。テックブログ、今週の担当は浦です。
最近は開発の上流工程を担当していたので、テックブログのテックってなんだっけ・・・と若干悩みつつ、今回は「使いやすいUI」とはなんぞや?というテーマで軽くまとめてみます。

ユーザーにとっての使いやすさ

使いやすいかどうか、直感的かどうかは、ユーザーによってそれぞれ異なります。
えーーーって思った方、すみません。ですが、業務アプリの設計過程で様々なお客さんとお話してきた経験上、今まで使っていたものに近いもの、見慣れたものを「使いやすい」とする人が大半でした。
どのようなUIに慣れているかは人によって異なるので、何を直感的と感じるかも人によって異なるわけです。
したがって、ここではユーザーの「慣れ」の要素は考慮せず、どのようなルールを持たせたUIがいいのか人間工学をもとに挙げてみます。
 

人間に合わせたUI設計のルール

1. 関連の高い要素は近づけて配置する

人間は、位置的に近くに配置されたものを関連のある情報として認識します。
例えば、画像とキャプションがその他の要素間より近くに配置されていれば、一目でどのキャプションがどの画像を説明しているのか判断できます。
逆に関連の低い要素間は、意識して余白を大きく取ることで区別しやすくなります。

2. 同じ要素・レイアウトを意識的に繰り返す

人間は、過去の体験から予測して行動します。
慣れたものは使いやすいと前述しましたが、それは1つのアプリ内でも同様のことがいえます。
ボタン配置等のレイアウトをどの画面でも統一すれば、何がどこにあるのかすぐわかるため、ユーザーは直感的に操作できます。

3. 重要な要素を左上から右下への対角線上に配置する

人間の視線は左上から右下へと移動します。「グーテンベルク・ダイアグラム」とも呼ばれますね。
例えば画面下部にボタンを配置している場合、重要な機能のボタンは右に置いた方が意識されやすいです。

4. 重要な要素は大きくする

何を当たり前のことを!と思われるかもしれませんが、人間の視線は大きいものから小さいものへ移動します。
情報の重要度によって表示する大きさを分けることは、シンプルですが効果が大きいと思います。

5. 関連の高い要素を同じ配色にする

人間の視線は同じ色のものへ移動します。
グルーピングできる要素同士や、重要度が同じ要素同士を同じ配色にすることで、関連要素を辿りやすくなります。

まとめ

人間工学的にどのようなUIが使いやすいか挙げてみました。
ちなみに、1.2. はデザインの4大原則の1つでもあります。
興味のある方は調べてみていただければと思います。

ImageMagickコマンドの注意点

こんにちは。イメージマジック三浦です。 2019年が後半に入りました。あっという間に半年過ぎたとも、まだ半年あるんだなとも思います。 今回は「ImageMagickコマンドの注意点」と題して書きます。
業務で、WindowsOSに導入することを念頭に ImageMagickコマンドを調査しましたが、その時に気づいたことを書いてみます。

ImageMagickとは

画像の変換や表示、内部情報などを見るソフトウェア群です。詳しい説明は他のサイトを参照してください。
 https://imagemagick.org/index.php 

インストールについて

ImageMagick開発元が、様々なOS向けにインストーラを提供しています。
特にWindowsOS用では、インストーラ方式のものと解凍して配置するだけのものがありますが、今回はWindowOS向けのポータブル版を使うことにしました。 ImageMagickコマンドの動作には、VC2013再頒布可能パッケージのインストールが必要とされています。最初のパッケージの後に、更新版が出ていますので、導入が必要だとすれば更新版の方がよいかと思います。
(VC2013再頒布可能パッケージ)
https://www.microsoft.com/ja-jp/download/details.aspx?id=40784
(VC2013再頒布可能パッケージの更新版)
https://support.microsoft.com/ja-jp/help/3138367/update-for-visual-c-2013-and-visual-c-redistributable-package
ただし、OSによっては同パッケージをインストールしなくても動いてしまうケースがあるので、実際の画像を使った動作確認は欠かせません。

動作確認をしてみて気づいたこと

WindowsOS向けのポータブル版ImageMagickを動作確認をする中で、ImageMagickコマンドの1つ「convert」が動かないという現象がありました。 以下のようなディレクトリ構成で、
E:\hoge
[D] ImageMagcik
[F] test.psd
PowerShellで、カレントディレクトリをImageMagick直下に移動してconvertコマンドを実行すると、以下のような結果が出ます。
(convertコマンドの詳細は割愛します)。
PS E:\test\ImageMagick> convert ../test.psd[0] ../test.png
無効なパラメーターです - /test.psd
PS E:\test\ImageMagick>
1つ上の階層のディレクトリに「test.png」というファイルができると期待したのですが、エラーになりました。
「convert /?」と入力するとWindowsOSのコマンドのヘルプが出てきたので、ImageMagickの「convert」コマンドを実行するつもりが、WindowsOSの「convert」コマンドを実行していたと考えられます。特に、コマンドプロンプトだと発生しないので、混乱しやすいところです。 PowerShellで期待した結果を得るには、以下のように指定する必要がありました。
PS E:\test\ImageMagick> ./convert ../test.psd[0] ../test.png
または
PS E:\test\ImageMagick> .\convert ../test.psd[0] ../test.png

同じような現象を回避するために

今回のような現象を回避するには、先頭に「.\」を付加してカレントディレクトリのコマンドであると明示する方法が無難だと感じました。「.\」が付いていれば、コマンドプロンプトでもPowerShellでも同じ動きをしてくれるためです。 他には「convert」コマンドが、最新バージョンの1つ前のImageMagick6系と互換性を維持するために提供されるものなので、最新バージョンの「magick」コマンドを使うことが考えられます。

最後に

これから暑くなるので、体調の管理には気を付けてください。
個人的には、睡眠時間の確保と毎日の食事でネバネバ食材を食べることに気を付けていますが、身体が軽くなったように感じているので、これからも続けていきたいと思います。

アイコンを作ってみました 19/06/05

はじめに

東京もそろそろ梅雨に突入しそうな6月です。廣田です。

最近はあまりtechなことをしていないので、techじゃないブログになりそうですが先日アイコンを作る機会があったので、気がついたことを書こうと思います。

アンチエイリアスのいたずら

PC画面上では有用なデザインソフトの便利機能が、実際に印刷されると思わぬ結果となって現れることがあります。

そのひとつがアンチエイリアスだと思います。

以前はよくphotoshopで漫画を描いていたのですが、デジタルで原稿データを作成する場合、アンチエイリアスをかけたまま入稿してしまうとトーン部分(よく漫画にあるドット柄のこと)に予期せぬ幾何模様が浮き出てくる「モアレ」という現象が発生します。
そのため入稿時は必ず二値化を行ってアンチエイリアスを無効化していました。

似たようなことが弊社サービスのオリジナルプリントでも起こるようで、お客様が入稿されたデータにかかっていたアンチエイリアスのせいで予期しない色が出てしまったりもするようです。

こと印刷と相性が悪いアンチエイリアスは面倒な存在だったりしました。

いざアイコン作成

そんないつもの感覚でアイコンを作成して画像を差し替えてみました。
かなりジャギーが気になる結果に。。

ここで忘れ去っていたアンチエイリアスを強めにかけてみました。
滑らかになりました!
アイコンのような小さく表示される画像の時は特にジャギーが出てしまうようで、こんな時、アンチエイリアスは有効なのだなと今更ながら気づきました。

幅広い業務に関われます。

趣味のブログのようになってしまいましたが、今回作成したアイコンは弊社サービスのODPSのクライアントシステムのアイコンで使われていたりします。

開発本部では作成したバーコードやRFIDタグをリーダーでピコピコ読み込んでいる方がいたり、DAS(デジタルアソートシステム)を導入するために何やらライトを光らせている方がいたり、工場のプロセスを省力化するために幅広い業務を行っています。

おそらく普通のIT企業のプログラマーさんよりも、興味があれば色んな技術に関われるのがイメージマジックの面白さかもしれません。

気になった方は弊社求人情報を覗いてみてください!  

これからのJavaとの付き合い方を考える

はじめに

イメージ・マジックの安藤です。
皆さんは、GWはどのように過ごされたでしょうか? 私はひたすら配信サイトで映画を探して見ていました。小さい頃に何となくテレビで見た映画を改めて見るのもまた面白いものだと感じています。


さて、今回はユーザーエンドのJava、いわゆるPublic JREと近年のJavaを取り巻く環境の変化についての話です。
話の大元となるのはこちらの記事です。

JDKのリリースモデルとライセンスの変更

Java9リリース後、JDKは9月と3月の6ヶ月ごとにリリースされるようになりました。Oracleによれば、大きな機能の進捗に引っ張られて中小機能のリリースが滞ることを危惧してとのことです。
JDKのライセンスも変更になっています。ライセンスはBCLからGPL v2.0に変更されており、加えてOracle JDKとOpenJDKの機能的な違いはJava11からはなくなりました。Oracleが配布するJDKが終了することばかりが注目されていますが、この変更の本質はJRE/JDKを容易に再配布可能にすることにあるようです。
Oracleは、現在のJavaが「JREをPCにインストールして画一的に実行する」方式であることにいくつかの弊害があるとしており、JREをアプリケーションにバンドルするための方式の整備を進めています(Java9で新たに登場したモジュールもそのための改善の一環です)。

Java11以降のPublic JREの廃止と新たなアプリケーション配布方式

前述の通り、OracleはJREのアプリケーションバンドルを徐々に推し進めています。そのような中で、Java11からはPublic JRE、つまりJavaの公式サイトで入手できるJREは廃止されています。現在配布しているのはJava8ですが、個人使用のユーザに対しての無償アップデートは2020年12月末まで、それ以外の無償サポートは2019年1月に終了しました。
Java11ではjlinkというバンドル用JREを作成する機能が付いています。アプリケーションに必要なモジュールを抽出するためのjdepsという機能も付いています。今年9月にリリースされるJava13にはjarからマルチプラットフォーム向けのアプリケーションやそのインストーラを作成するjpackageという機能も追加される予定です。
バンドル用JREの作成に際してはこちらのサイトを参考にさせていただきました。

業務での方針を考える

弊社で開発中のアプリケーションではPDFの帳票印刷にJavaを使用しています。現在は実行可能JarをPCにインストールされているJavaで実行していますが、JREを配布して実行できるような仕組みを追々作成していく必要があるでしょう。 テストとしてバンドル用のJREを作成してみましたが、40MBほどの容量になりそうです。
配布するために一度圧縮する必要やアップデートの方法など検討事項がいくつかありそうなので少しずつ進めていく予定です。

PHPでPDF帳票を作成する

はじめに

こんにちは、イメージ・マジックのもあいです。

春になり、JリーグやMotoGP等のスポーツも今シーズンが開幕、UCLや欧州サッカーも終盤を迎えて情報を追ったり観戦したりするのが大変な状態です。インターネットが発達してこんなに情報が増えようとは思いもしなかった今日この頃です。 今回はPHPでPDF帳票を作成するために必要だったことをまとめてみました。

使用するライブラリ

FPDFmPDFwkhtmltopdf という選択肢から、mPDFを使用しました。選定した理由は扱いやすさとライブラリ自身がそれなりの頻度で更新されているからです。

インストール

composerでインストールできます。
composer require mpdf/mpdf
そのほかに日本語を表示させるのであれば日本語フォントが必要になります。

使い方

htmlとcssを用意する

mPDFはhtmlとcssでPDF帳票のレイアウトを作成します。htmlなのでポジションを調整するのが難しいと思われますが、cssのposition:absoluteが条件付きで使用することができます。

ドキュメントにも記載されているのですが、body要素の直下の要素にだけposition:absoluteが適用できます。これを使うことによりレイアウトを調整できます。単位もpxでは無くてptやmmが使えますので帳票レイアウトの調整はそれほぞ難しくないです。
下記のようなコードの場合aクラスとbクラスはposition:absoluteが適用できますが、cクラスは適用できません。
<body>
  <div class="a"></div>
  <div class="b">
    <div class="c"></div>
  </div>
</body>

htmlを取得する

弊社ではSymfony4を使用して開発していますので、htmlを取得する場合はコントローラのrenderViewメソッドでtwigとデータを渡すとhtmlが取得できます。

PDFを生成する

mPDFのインスタンスを生成するときに設定情報を配列で引き渡します。この時に用紙の大きさ/向き/マージンやフォントファイルの場所やフォントにkanする方法を引き渡します。 設定情報はだいたい下記の通りです。
$config = [
    'mode' => 'ja+aCJK',
    'format' => [297, 210],
    'dpi' => 200,
    'tempDir' => '/tmp/',
    'margin_left' => 0,
    'margin_right' => 0,
    'margin_top' => 0,
    'margin_bottom' => 0,
    'orientation' => 'P',
    'fontDir' => [
        '/path/to/fontDir/,
    ],
    'fontdata' => [
        'ipag' => [
            'R' => 'ipag.ttf',
        ],
        'ipagp' => [
            'R' => 'ipagp.ttf',
        ],
    ],
];
A4縦でDPIは200、フォントにIPAゴシックとIPAゴシックプロポーショナルを指定し、fontdataの配下のipagとipagpというキーはcssのfont-familyで指定することができます。

設定情報をmPDFのインスタンスに渡してWriteHTMLメソッドを呼び出してからOutputメソッドを呼び出すとPDFを標準出力に出力します。
Symfony4で標準出力の結果をクライアントに送信する場合はStreamedResponseクラスを使用することになります。
$mpdf = new \Mpdf\Mpdf($config);
$mpdf->SetDefaultFont('ipagp');
$mpdf->WriteHTML($html);
$mpdf->Output();

最後に

htmlで帳票を作成するに際に、位置がずれると問題になる帳票を作成した際に調査した結果です。

Google chromeでの2種類のスクリプトテスト

株式会社イメージ・マジックの技術ブログ、今週の担当のsoenoです。


今日は4月の初めの日です。

新学期かつ新元号の発表の日となります。

11時半が発表だそうです。

そんな節目のテックブログ何となく大事に思えるのですが、大丈夫でしょうか?

元号はともかく、今日の担当も実はエイプリルフールだったりしないかなと思いつつ始めます。

ブラウザでのスクリプトを動かすとき

あまり使わない関数の書き方に迷ったとき、

そういう時はコマンドラインでスクリプトを動かすとテストできます。

コンソールからスクリプトの実行

手順は以下の通り

  1. chromeブラウザでF12キーを押して DevToolsを立ち上げ
  2. メニューバーのConsoleを選択
  3. アクティブになっているテキストエリアにスクリプトを入力してEnter
https://www.google.com/で試す場合

  • まずhttps://www.google.com/に移動して
  • コンソールに以下のスクリプトを入れてEnter!
[HTML] document.forms.f.q.value = “新元号”; document.forms.f.submit(); [/HTML] 新元号についての検索結果がでます。

スニペットからスクリプトの実行

手順は以下の通り

  1. DevToolsのメニューバーのSoursesを選択
  2. 左のメニューのSnippetsを選択(なければ横の矢印を押して出てくるlistから選択)
  3. New Snippedの左の+ボタンを押して新規のSnippetを作成
  4. 空白のエリアに実行したいスクリプトを入力
  5. Ctrl と Enterを同時に押すか、右下の再生ボタンをクリック。
https://www.google.com/で試す場合

  • まずhttps://www.google.com/に移動して
  • 上の手順でSnipedの入力画面まで進み、
  • 以下のスクリプトを入力しCtrl + Enter!
[HTML] var searchForm =document.forms.f; searchForm.q.value = “新元号”; searchForm.submit(); [/HTML]

注意点

jQueryなどのプラグインの動作を試したいといった場合は対象のプラグインが読み込まれている必要があります。

※例のgoogleページへのスクリプトは内部の変数などかわってたら来ません。

終わり

最後の平成に間に合わせようと駆け足になりましたが、以上です。

新しい元号の新しい時代が良いときとなりますよう…。

Ubuntuについて2

岡野です。
前々回のブログ「Ubuntuについて」の続きです。
Ubuntuの良い所を書きます。

メリット2 サポート期間の延長が可能

当社にはUbuntu14を使用しているサービスが一部あり、まもなく5年のサポート期間が切れます。 OSをバージョンアップするのは大変なためESM(Extended Security Maintenance)を導入するかもしれません。
ESMとは主要なパッケージについて有料でセキュリティパッチが提供されるサポートサービスです。 但しESMにはUbuntu12での実績によるとImageMagick等がサポート対象に入っていない様です。 そのためESMを導入してもApache等を除く個々のソフトウェアについては個別に対応する必要がありそうです。
なお他のLinuxディストリビューションでは無料サポート期間が5年以上の物も一応あります。

メリット3 情報が見つけやすい

最近ImageMagickの動作速度が遅く感じられることがあり、Meltdown等の対策パッチの影響かと思って色々と調べました。 Ubuntuのパッチについての情報はすぐに見つかりました。
上記は公式サイトの例ですが、stackoverflowやserverfaultなどでもUbuntuの情報は他のLinuxディストリビューションより見つけやすい気がします。
なお少々古い環境ですが実験した所では以下の通り、Meltdown等の対策パッチによるImageMagick動作速度への影響はありませんでした。
・CPU
Xeon E5-2407
・OS
Ubuntu 14.04(パッケージ最新状態)
・カーネル
3.13.0-167-generic #217-Ubuntu SMP Wed Mar 13 16:18:21 UTC 2019 x86_64
・パッチ無効化方法
grubで”nopti nopcid noibrs noibpb nospectre_v2 nospec_store_bypass_disable”を指定。
・コマンド実行
“time convert 7134×7134.png -colorspace rgb -strip png32:test.png”を試したが、パッチ状態に関わらず共に12.6秒。

分かりやすいエンドポイントの設計

こんにちわ!やっとこさ入社1ヶ月半の浦です。
毎年この時期は花粉にやられています。ただただつらいです。鼻の粘膜を焼いてアレルギー反応が起こりづらくする治療もあるようですが、ちょっと怖いのでチャレンジできずにいます。花粉面倒なので、どなたかGWまでタイムリープする方法を知りませんか?

今回のテーマ

さて、現在私は【ODPS】 という、工場受注~生産管理までを一括で担うクラウド管理 システムの開発に携わっています。詳しくは以下のリンクをご覧いただければと思います。
https://imagemagic.jp/service/odps/

クラウド管理システムなので、当然ながらWebサービスです。
TwitterでもYouTubeでも何でもかまわないのですが、Webサービスのエンドポイントの設計って気になりませんか?個人的にはけっこう見ちゃうんですよね。
APIを使う際、URIの設計が悪いと使い方を理解しづらかったり、間違って使ってしまったり・・・。ということで今回は、分かりやすいエンドポイントの設計について考えてみたいと思います。

余計な情報がない

例えば、以下のURIを見てどう思われるでしょうか。
  • http://example.com/service/users/get
個人的な突っ込みどころは二つです。

1.「service」が抽象的

大抵「サービス」という単語が出てくると、より具体的な機能を当てはめた単語に置き換える必要があるか、その単語自体不要なことが多いかと思っています。

2. 「get」は不要

HTTPのメソッドで使い分ければいいですね。URIの指すリソースと、そのリソースに対する操作は分離できた方が見やすいです。

単語を省略しない

  • http://exapmle.com/sv/u
このURIを見て、どんなリソース・機能にアクセスするのか分かるでしょうか。「sv」は「service」かもしれませんし、「supervisor」かもしれません。「u」も省略し過ぎて「user」なのか判然としませんよね。
人間が見てどのような機能なのか理解できないURIは、タイプミスに繋がります。APIを公開してクライアントにアクセスしてもらうことになった場合、上に挙げたような理解しづらいURIは、クライアントの開発効率の低下に繋がると考えます。

大文字小文字が混在していない

大文字小文字が混在しているとは、例えば以下のようなケースです。
  • http://example.com/Users/0123
URIのすべてが小文字に統一されていれば、この単語は大文字だったっけ?と迷うことがなくなります。また、ホスト名の部分はすべて小文字での表記が一般的ですので、それに合わせてすべて小文字にするのが良しとされているようです。

集合は複数形

  • http://example.com/user/0123
一見上記URIは、意味も分かりますし適切に思えます。しかし、上記URIの示すところは、「ユーザー」という集合の中の、「0123」というリソースです。データベースのテーブル名は一般的に複数形が適切といわれているのと同様で、集合を表すものは複数形にするのが一般的です。

まとめ

簡単ではありますが、今回は分かりやすいエンドポイントの設計について考えてみました。
エンドポイントの設計にご興味のある方は、ProgrammableWebという様々なAPIをまとめたサイトがお薦めです。各サービスがどのようなエンドポイントになっているか眺めるだけでも勉強になります。
URIの設計に限らずコーディングもそうですが、分かりやすさという観点は忘れずに今後の開発に取り組んでいきたいものです。

PowerShellにLinuxコマンドを見る

こんにちは。イメージマジック三浦です。
朝晩の寒さは残りますが、梅の花が咲いているところやプロ野球オープン戦の話題が出てくるようになりました。一方で最近降った雨は冷たかったです。暖かくなるのはもう少し先のようです。

今回のテーマ

今回は「PowerShellでLinuxコマンドを使ってみる」と題して書きます。 かねてより、lsやcurlを起動できることは知っていたのですが、 気になったので正体を調べてみました。

早速試す

実際にPowerShellでコマンドを打ってみると、以下の結果となります。オプションまでLinuxと同じということはないようです。
  • 使える:ls, ls -R
  • 使えない:ls -l
PS C:\hogehoge> ls


    ディレクトリ: C:\hogehoge


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2019/03/01     12:42                subdir
-a----       2019/03/01     12:41              3 aaa.txt
-a----       2019/03/01     12:41              3 bbb.txt
-a----       2019/03/01     12:41              3 ccc.txt


PS C:\hogehoge>
PS C:\hogehoge> ls -R


    ディレクトリ: C:\hogehoge


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2019/03/01     12:42                subdir
-a----       2019/03/01     12:41              3 aaa.txt
-a----       2019/03/01     12:41              3 bbb.txt
-a----       2019/03/01     12:41              3 ccc.txt


    ディレクトリ: C:\hogehoge\subdir


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2019/03/01     12:42              6 ddd.txt


PS C:hogehoge>
PS C:\hogehoge> ls -l
Get-ChildItem : パラメーター 'LiteralPath' の引数が指定されていません。型 'System.String[]' のパラメーターを指定し、再
試行してください。
発生場所 行:1 文字:4
+ ls -l
+    ~~
    + CategoryInfo          : InvalidArgument: (:) [Get-ChildItem]、ParameterBindingException
    + FullyQualifiedErrorId : MissingArgument,Microsoft.PowerShell.Commands.GetChildItemCommand

PS C:\hogehoge>

昔からあるWindowsのコマンドは?

ディレクトリ配下の一覧を返すコマンドとして、以前からdirというものがありました。ここでdirを実行してみると、lsと同じ結果が返ってきます。
PS C:\hogehoge> dir


    ディレクトリ: C:\hogehoge


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2019/03/01     12:42                subdir
-a----       2019/03/01     12:41              3 aaa.txt
-a----       2019/03/01     12:41              3 bbb.txt
-a----       2019/03/01     12:41              3 ccc.txt


PS C:\hogehoge>

正体を探る

lsとdirで同じ結果が出るのは判りましたが、何故かはわかりません。これを調べるために、ls のヘルプを見てみます。
PS C:\hogehoge> ls -?

名前
    Get-ChildItem

概要
    Gets the items and child items in one or more specified locations.

…
Get-ChildItem という名前が出てきました。これが正体のようです。
lsを実行すると、「Get-ChildItem」というPowerShellコマンド(コマンドレットと言われます)が実行されます。 dir でも同じ結果が出てきます。
PS C:\hogehoge> dir -?

名前
    Get-ChildItem

概要
    Gets the items and child items in one or more specified locations.

…

「Get-Children」の別名を確認

最後に、「Get-Children」コマンドレットが持つエイリアスを確認してみます。
PS C:\hogehoge> Get-Alias | Where-Object { $_.Definition -eq "Get-ChildItem" }

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           dir -> Get-ChildItem
Alias           gci -> Get-ChildItem
Alias           ls -> Get-ChildItem


PS C:\hogehoge>
ls, dir の他に gci という別名がいることも分かります。

まとめ

PowerShellで「ls」や「curl」が打てた、というところを出発点に調べてみました。Linux系OSで使えたコマンドを試しに打ってみたら実は使える、というものが他にもあるかもしれません。また使えなかったとしても、自分でエイリアスを設定することもできるようです。
スクリプトを作る時は、使おうとしているエイリアスが実行先の環境で設定されているかを確認する必要がありますが、技術的な選択肢の1つの手段として、上手く使っていければと思います。

Doctrine オブジェクトレベルのトランザクション

はじめに

廣田です。東京は2月あたりのこの時期が一番寒いですね。(;´T`)ズズッ

この間、絶版した雑誌の記事がどうしても読みたくて国会図書館オンラインを初めて利用しました。
日本で出版された書籍を全て所蔵しているともいわれる国立国会図書館ですが、行かなくてもオンラインで記事(複写)を購入できるようになっているんですね。(知らなかった…)

使ってみた感想ですが図書館のサイトと侮るなかれ。
まるで大手通販サイトなみの使い勝手の良さに驚きました。
記事を「カートに入れる」んだぁ…💡

図書館らしいシンプルなデザインでありながら、わかりやすい操作性は個人的に大変勉強になるものでした。

創刊当初の週刊少年漫画なども所蔵しているので、機会があれば利用してみてはいかがでしょうか。
https://ndlonline.ndl.go.jp


さて今回はsymfonyで利用されているORMのDoctrineについて、
トランザクション中で、persistされたエンティティってflushされるまでどこに貯まるんだろうと疑問に思い調べたので、備忘としてメモしようと思います。

背景

以下のような感じでCSVファイルからデータを取り込んでDB登録している機能を作っていました。


 ・・・・
$file = $uploadForm->getData()['file'];
/** @var EntityManagerInterface $em */
$em->beginTransaction();
$errors = $csv->upload($file->getFileInfo(), $csvHeader, $callback);
     //↑ここで1行1行エンティティに変換してpersistしていたりする。
if (count($errors)) {
                $em->rollback();
                $this->addFlash('warning', 'エラーが発生したため登録していません。');
            } else {
                $em->commit();
                $this->addFlash('notice', '登録しました。');
            }
   ・・・・

CSVデータに内容がダブっている行があった時にそこはpersistしないようにしたいなぁ…
⇒ すでにpersistされているエンティティと今見ているCSVデータの内容を比較したいなぁ…
⇒ 同一トランザクション中ですでにpersistされているエンティティってどうやって取得すればいいんだろう??
というきっかけでした。

UnitOfWorkのサイクル

Doctrine公式のドキュメントによると、UnitOfWorkはオブジェクトレベルのトランザクションのようなものと表現されています。
https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/working-with-objects.html#working-with-objects

EntityManagerが生成された時、あるいはEntityManager->flushを発動した後に新しくUnitOfWOrkのサイクルが開始されるのだそう。
そのサイクルの中で変更をトラッキングし、データベースに正しい順序で書き込む役割を担う…とのことで
ここを見ればpersistされたエンティティを取得できそうと考えました。

UnitOfWorkへのアクセス

公式ドキュメントでは$em->getUnitOfWork();でUnitOfWorkにアクセスできるとしか書いてなかったので、 UnitOfWOrk配下の関数を一通り見ていると、それっぽい名前のものを発見。

$em->getUnitOfWork()->getScheduledEntityInsertions();//←これ


さっそく使ってみると、persistされているエンティティの一覧を配列で返してくれました。

他にもgetScheduledEntityUpdates()、cheduledEntityDeletions()などがあり、UnitOfWorkがトラッキングしているエンティティを状態ごとに取得できるようになっています。

さいごに

Doctrineってこういうライフサイクルなんだなーと、ほんっっっの少しだけ仕組みが理解できたような気がしました。