PHPで半角数字を漢数字の単位付きの表記に変換したい
530000
→ 53万
みたいに漢数字の単位を付けたかった。
タイトルに漢数字って書いてあるから詐欺ってるみたいだけど五三万
への変換は今回はやりません。🙇🏿
早速コード
<?php function convert($value) { // 1000以下の場合は単位を付けずに返却 if ((int) $value < 1000) { return (string) $value; } $units = ['', '万', '億', '兆', '京']; // 右から桁数を分割していく $splits = array_reverse(str_split(strrev($value), 4)); // 桁数によって使用する単位の調整 array_splice($units, count($splits)); $filterUnits = array_reverse($units); $convert = ''; // 反転した数値を元に戻して単位をつける foreach ($splits as $index => $split) { // 0000の場合、表記を省略する $convert .= (int) $split === 0 ? '' : number_format(strrev($split)) . $filterUnits[$index]; } return $convert; } assert('私の戦闘力は53万です。' === '私の戦闘力は'.convert('530000').'です。'); // true
感想
- 単位が飛ぶ時の表記をどうしようか迷ったけど, 単位が
0000
の場合は省略するようにした。
(100000001
の場合,1億0000万0001
ではなく1億1
の表記になる) - 反対に, 漢字(
53万
) → 半角数字(530000
)に変換するのも考えたけど, 意外とやることが多くて諦めた。
必要に迫られたらやる。(やらないフラグ) - 漢字単位への変換前に文字列に変換すれば京以上の単位も付けれるんだろうけど, お金周りの変換がしたかっただけだから考慮してない。
PHP_INT_MAX
を超過する数値を扱いたい人はこっち来ないで😭😭😭 - 全体的にトリッキーなので誰か別の方法ご存知でしたらご指摘ください🙏🏻
- JSでやったほうが需要ありそう
ブラウザの Console をタイマー代わりに使う
電卓使いたいときにブラウザの Console 使う人間なので、タイマーも Console で完結させたかった
1秒ごとに Console に秒数を表示する
let sec = 0; const intervalId = setInterval(() => { ++sec; console.log(sec); }, 1000);
特定の秒数になったらカウントを停止する
let sec = 0; const intervalId = setInterval('countSec()', 1000); const countSec = () => { if (sec === 5) { clearInterval(intervalId); alert(`${sec}秒が経過しました。`); return; } ++sec; console.log(sec); }
特定の秒数になったら、ダイアログを押すまで通知音を鳴らす
let sec = 0; const intervalId = setInterval('countSec()', 1000); const audio = new AudioContext(); const oscillator = audio.createOscillator(); oscillator.type = 'sign' oscillator.connect(audio.destination); const soundStart = () => { oscillator.start(); } const soundStop = () => { oscillator.stop(); } const countSec = () => { if (sec === 5) { clearInterval(intervalId); soundStart(); alert('タイマーを止める。'); soundStop(); return; } ++sec; console.log(sec); }
いつ使うの?
PCがネットに繋がらない状況でカップ麺を作らなければならないとき
感想
こんなん書くくらいだったら普通にタイマーアプリ使うわ
最低限通知音は必須だけど毎回書いとれん😊
もっと簡潔に書ける方法あったら誰か教えて下さい 🙏🏻
Bootstrap を使ってテーブルの行をクリックした時にコンテンツを展開したい
テーブルの各行をクリックした時に行の下にコンテンツを表示する。
一覧に表示する列数が多いけど横スクロールしたくないときに使う。
tr > td の中に div を書いてたりするのでマークアップ警察は見るな
要点
① クリックする行の tr タグに開閉トリガーをつける
<tr data-toggle="collapse" data-target="#collapse-1">
② クリックする行の tr タグの直下に tr > td でラップした開閉コンテンツを設置する
td 要素は1つだけにして, 開閉トリガーの列数分の colspan で結合する
<tr> <td colspan="4" class="p-0"> <div class="collapse" id="collapse-1"> <p>開閉コンテンツ</p> <p> 親譲りの無鉄砲で小供の時から損ばかりしている。小学校に居る時分学校の二階から飛び降りて一週間ほど腰を抜かした事がある。なぜそんな無闇をしたと聞く人があるかも知れぬ。別段深い理由でもない。新築の二階から首を出していたら、同級生の一人が冗談に、いくら威張っても、そこから飛び降りる事は出来まい。弱虫やーい。と囃したからである。小使に負ぶさって帰って来た時、おやじが大きな眼をして二階ぐらいから飛び降りて腰を抜かす奴があるかと云ったから、この次は抜かさずに飛んで見せますと答えた。(青空文庫より) </p> </div> </td> </tr>
感想
個人的にはあまり好きなUIではないので必要に迫られた時以外使いたくない🤔
Laravel で ORDER BY を複数指定する
Laravel で
SELECT * FROM samples ORDER BY column1 DESC, column2 ASC
みたいに ORDER BY を複数指定したい場合の書き方
<?php App\Models\Sample::orderBy('column1', 'desc')->orderBy('column1', 'asc')->get();
もしくは
<?php App\Models\Sample::orderByDesc('column1')->orderBy('column1')->get();
何故か毎回連想配列でできると思いこんでApp\Models\Sample::orderBy(['column1' => 'desc', 'column1' => 'asc'])->get();
みたいに書いてはエラー→ググる→修正のループを繰り返してたけどこれで覚えるだろ。。。
参考
Vue.js でファイルアップロードをする
Vue.js というより axios でファイルアップロードをしたかった
保存ボタンがなく、アップロード時にサーバーに送るのを想定
サーバーサイドのFWは Laravel を想定
<template> <div> <!-- ファイルアップロード用の input --> <input type="file" ref="image" accept="image/*" name="image" @change="uploadImage" /> </div> </template> <script> import axios from "axios"; export default { name: "InputFile", methods: { uploadImage() { // parameter の用意 const params = new FormData(); params.append("image", this.$refs.image.files[0]); axios .post(`${process.env.MIX_APP_URL}ファイルアップロード先のURI`, params, { headers: { "Content-Type": "multipart/form-data", Authorization: "XXXXXXXXXXXX", }, }) .then((res) => { console.log(res, res.data); if (res.status !== 200) { console.error("画像のアップロードに失敗。"); return; } // サーバー側のレスポンスに合わせてエラーハンドリングなど if (!res.data.succeeded) { console.error("画像のアップロードに失敗。"); return; } // アップロード成功時の処理 console.log("画像アップロードに成功。"); }) .catch((error) => { console.error(error, error.response); // Laravel のバリデーションエラーの場合のレスポンスに合わせてエラーメッセージを出力 if ( error.response.status === 422 && error.response.data.errors.length !== 0 ) { console.error(error.response.data.errors.image); return; } // その他のエラー console.error("画像のアップロードに失敗。"); return; }); }, }, }; </script>
axios でファイルアップロードってやったことないからどうやるんだろうって思ってたけどよくよく考えたら FormData でパラメータをセットしてPOSTすればいいだけの話だった
参考
株式会社エイルシステムではWebエンジニア・モバイルアプリエンジニアを募集しています。
実務経験がなくてもOKです。ご興味のある方は弊社HPよりご連絡ください。
HTML と CSS のみでドラえもんを作る
(割とやりつくされたネタだから今更感すごいけど。。。)
[ドラえもん CSS] とかでググると実装方法がわかってしまうため今回は終始ググらないようにして実装
できたもの
実装
感想
所詮丸と直線の組み合わせだし position とか使わんくても Flexbox だけでモダンなドラえもん作ってやるぜ!!!って思って手を出したけど意外とムズかった。position 使いまくって結局泥臭いコードになってる。(HTML構造のせいかもだけど)
完成後に他の方のドラえもんも見て回ったけど↓このドラえもんの完成度が圧倒的だった。体もあるし
後これも。
俺の想定してたドラえもんの口がまさにこれ
qiita.com
おまけ
作成過程で生み出されたバケモンたちの供養
JSでブラウザの位置情報を取得する
(function () { if (!navigator.geolocation) { console.warn("Geolocation APIを利用できない環境"); return; } navigator.geolocation.getCurrentPosition( (positions) => { // 位置情報の取得成功時の処理 console.log(positions.coords.latitude, positions.coords.longitude); }, (error) => { // 位置情報の取得失敗時の処理 const errors = { 1: '位置情報の利用が許可されていない。', 2: '位置情報の取得に失敗。', 3: 'タイムアウト。' }; console.error(error.code, errors[error.code]) }, { enableHighAccuracy: true, timeout: 5000, maximumAge: 0, } ); }());
options詳細
option | デフォルト | 説明 |
---|---|---|
enableHighAccuracy | false | 精度の高い位置情報を取得するか GPSを使うことができる場合に使う |
timeout | 無制限 | タイムアウトまでの時間 |
maximumAge | 0 | 取得済みの位置情報の有効期限 |
ブログ用に書いてるから可読性死んでるけどプロダクトに使うときはコールバック関数は別で定義しようね。。。
参考
developer.mozilla.org developer.mozilla.org developer.mozilla.org
JSで任意の個数分の配列を作成する
PHPで言うところの range(1, 20)
をやりたかったけどJSにはそれらしき機能がなく毎回調べているのでメモ
[...Array(5).keys()] // [0, 1, 2, 3, 4]
Array.from(Array(5).fill().keys()) // [0, 1, 2, 3, 4]
indexを0以外から始めたいときはmapで足してあげる
[...Array(5).keys()].map(row => row+3) // [3, 4, 5, 6, 7]
単純に個数分だけ作成したいときはArray(5).fill()
でOK
配列を任意の個数で分割したい
array_chunk()
みたいに全部均等ではなく, 3個, 2個, 2個, 6個, 1個, 1個 ... みたいに分割数が可変な配列を作りたかったときに地味にハマったのでメモ
<?php $src = range(1, 15); $chunks = [3, 2, 2, 6, 1, 1]; // 分割したい個数 $offset = 0; $values = []; foreach ($chunks as $chunk) { $values[] = array_slice($src, $offset, $chunk); $offset += $chunk; }
結果
array(6) { [0]=> array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } [1]=> array(2) { [0]=> int(4) [1]=> int(5) } [2]=> array(2) { [0]=> int(6) [1]=> int(7) } [3]=> array(6) { [0]=> int(8) [1]=> int(9) [2]=> int(10) [3]=> int(11) [4]=> int(12) [5]=> int(13) } [4]=> array(1) { [0]=> int(14) } [5]=> array(1) { [0]=> int(15) } }
ちなみにハマったとこは最初 $offset
使わずに $values[] = array_slice($src, count($values), $chunk);
みたいな書き方してて、当たり前だけど offset が1個ずつしか増えてかんくて, 「なんで!??!?!?!?!」ってなってた🥰クソバカ🥰
参考
Terminal 起動時に 「You have new mail.」 と表示された場合の対処法
ホストマシンに設定したテスト用の cron が失敗してた時にメールが届いてた
放置してたけど地味に鬱陶しかったので対処したときのメモ
$ mail >U 1 # 未読のメールが件数分表示される >N 2 >N 3 >N 4 ? d* ? q
- mail コマンドで未読メールの一覧を表示
- 適当に件名で判断して全削除OKの場合はそのまま
d*
q
で終了
削除オプション
command | 意味 |
---|---|
d1 | 1だけ削除 |
d1 2 | 1と2を削除 |
d1-10 | 1~10を削除 |
d* | 全削除 |
先頭のアルファベットの意味
alphabet | 意味 |
---|---|
N | 新着 |
U | 未読 |
参考
Laravel でQueryBuilderで組み立てられたSQLを確認する方法
QueryBuilder(or Eloquent ORM)で組み立てたSQLを確認したい時に使う
いずれも tinker で実施
①QueryBulderから確認する場合
>>> App\Models\User::where('id', 1)->toSql() => "select * from `users` where `id` = ?"
②複数のQueryBuilderから確認したい場合
>>> DB::enableQueryLog() # ログの出力をONにする => null >>> App\Models\User::find(1) # SQLを確認したい処理分だけ実行する => App\Models\User {#370 id: 1, name: "example", email: "example@example.com", } >>> DB::getQueryLog() # 実施した分のSQLが出力される => [ [ "query" => "select * from `users` where `users`.`id` = ? limit 1", "bindings" => [ 1, ], "time" => 2.76, ], ] >>> DB::flushQueryLog() # ログの中身を空にする
適当なタイミングで DB::flushQueryLog()
をすればログの中身が空になる
毎回空にするのであれば dump(DB::getQueryLog()) && DB::flushQueryLog()
を実行すれば出力と同時にログの中身も空にしてくれる
参考
株式会社エイルシステムではWebエンジニア・モバイルアプリエンジニアを募集しています。
実務経験がなくてもOKです。ご興味のある方は弊社HPよりご連絡ください。
PHP で Selenium を動かすためにやったこと
Selenium 童貞捨てたのは Python だったけど使い慣れてる PHP でも Selenium を使いたかったので備忘録
以前やった内容を後日まとめてるのでもしかしたら手順に抜けがあるかも。。。
前提
- composer はDL済み
手順
1. ChromeDriver のダウンロード
自分の使ってる GoogleChrome と同じversionの ChromeDriver をDLして解凍する chromedriver.chromium.org
2. chromedriver のパスを通す
自分の場合は /usr/local/bin
に移動
mv ~/Downloads/chromedriver /usr/local/bin
※未検証だけど確か WebDriver で chromedriver のパスを指定できるようになってるはず
3. selenium-server-standalone のダウンロード
下記から適当に安定版をDL
www.selenium.dev
自分の場合はDL時にChromeのセキュリティ関係(?)でブロックされたのでシークレットモードで開いてDLした
4. selenium-server-standalone をホームディレクトリに移動
起動しやすい場所であればどこでもOK
mv ~/Downloads/selenium-server-standalone-xxxx.jar ~/
5. composer で php-webdriver/webdriver
のインストール
$ composer require --dev php-webdriver/webdriver
6. 適当なプログラムの作成
example.php というファイル名で作成
<?php use Facebook\WebDriver\Remote\DesiredCapabilities; use Facebook\WebDriver\Remote\RemoteWebDriver; use Facebook\WebDriver\WebDriverBy; require_once './vendor/autoload.php'; (function () { $host = 'http://localhost:4444/wd/hub'; $driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome()); $driver->get('https://www.google.com/'); $driver->findElement(WebDriverBy::cssSelector('input[name="q"]')) ->sendKeys('不死川実弥 過去 何巻')->submit(); })();
不死川実弥の過去が何巻だったかをググるだけのプログラム
7. selenium-server-standalone の起動
java -jar ~/selenium-server-standalone-3.4.0.jar &
8. プログラムの実行
php example.php
Macの場合、セキュリティ関係で初回は↓のようなポップアップが出てくるので、
システム設定>セキュリティとプライバシー>一般タブで開くことを許可する必要がある
9. プログラムが動くことの確認
これで PHP でも自動操作し放題だぜ!!!! (対象サイトの利用規約を必ず読みましょう)
WebDriver の操作方法もいつかブログにまとめたい。いつか。。。!
参考
github.com blog.shimabox.net qiita.com
株式会社エイルシステムではWebエンジニア・モバイルアプリエンジニアを募集しています。
実務経験がなくてもOKです。ご興味のある方は弊社HPよりご連絡ください。
USJ 行きましたメモ
※この記事にはUSJのアトラクションである 鬼滅の刃 XRライド や スーパー・ニンテンドー・ワールド に関するネタバレがあります。
知人の誕生日&鬼滅コラボを目当てにユニバ行ってきたので備忘録
エクスプレス・パスの購入
目当てが「鬼滅の刃 XRライド」だったから絶対待ち時間エグいだろうと思って事前に購入(購入にはClubユニバーサルへのアカウント登録が必要)
9/21のチケットを購入できるのが8/18~だったから8/18の0時になった瞬間にオンライン購入しようとしたけどアクセス集中のせいか、サイトが重くなって中々繋がらなかった
翌朝アクセスしたらみんなアクセスだけで購入はしないのかキャンセルしたのかわかんないけど、普通に繋がってスムーズに購入できた
当日行ったら最大240分待ちとかだったから本当に購入しておいてよかった。。。
入場券付きホテルの予約
前日にユニバから徒歩3分くらい?の入場券付きのプランでホテル泊まった
ホテル内ミニオンだらけで可愛かった🥰
入場待ち
AM9:00から入場可だったけど知人が禰豆子のポップコーンバケツが欲しいとのことなのでAM7:00くらいから一緒に入場待ち
ホテルの人曰く始発組がAM6:00くらいから並び始めるらしく、この時点ですでに結構並んでた
9月中頃だったけど日光強すぎたし日焼けしたくない人はまじで日傘は必須!!
入場
AM9:00入場かと思いきやAM8:45から入場できた。入場直前に持ち物チェックがあったんだけどペットボトル1本は持ち込みOKらしい。
入場した途端ほとんどの人が禰豆子のポップコーンバケツの売り場までダッシュしてった
クルーの方が一生懸命止めてたけどみんなガン無視だったwww
ちな自分も軽く速歩きしたけど単純に体力がないのでついていけなかった。。。
売り場についたときには既に長蛇の列で2つくらい折返し部分できてた。
40分くらい?並んで禰豆子GET🎉(知人のついでに並んだだけなので親にあげた)
はちみつうめ味のポップコーンがついてくるんだけど禰豆子が目当てだからなのかポップコーンは断っている人もちらほらいた😢
汚したくない+持ち歩くには普通に邪魔wなので購入後はロッカーに預けました
並んでる最中はほんとに↓こんな感じだった。 クルーの方も割り込み禁止の呼びかけはしてたけど、足元にソーシャルディスタンスの線が貼ってあるわけでもないから列は結構密だった。
これが大人気アトラクション禰󠄀豆子ポップコーンのQラインですか #USJ pic.twitter.com/iAA84k9Xw9
— Akihirojjj (@PUSJJJJ) 2021年9月18日
あとから知ったけど9時には完売してたらしい
#USJ 鬼滅の刃ポップコーンバケツ完売時間
— USJのツボ(USJで出会った心温まる物語) (@usj1) 2021年9月23日
9月
16日14時
17日10時30分
18日 9時10分(開園8時35分
19日 8時55分(開園8時25分
20日 8時55分(開園8時25分
21日 9時(開園8時45分
22日8時56分(開園8時45分
23日8時50分(開園8時30分
禰豆子ポップコーンバケツ#ユニバ #USJファン#USJ鬼滅の刃 #鬼滅の刃 pic.twitter.com/6imkjaD4Cc
アトラクションとか
体力的にエクスプレス・パスに含まれるアトラクションしか乗らなかったw
アトラクションで一番良かったのは圧倒的に 鬼滅の刃 XRライド だった🙌映像が綺麗すぎた🙌
入り口にある炭治郎と煉獄さん🔥
後ろに回ると禰豆子が顔出してて可愛かった🥰
マリオカートも期待してたんだけど3Dメガネ?が結構雑で期待はずれでした😭(雑というか横から現実が見える感じ)
ヨッシー・アドベンチャーはまじで子供向け。ヨッシーは可愛いけど個人的に一番いらんかったw
でもニンテンドー・ワールドの世界観はパークの中でずば抜けてよかった🤟
個人的にスマブラのコクッパの爆弾?があることに一番テンションあがった(コクッパ詳しくない)
右上に現実が見える😭😭😭
https://www.usj.co.jp/ticket/event/kimetsu/exp-7-ride.htmlwww.usj.co.jp
↑のエクスプレス・パスだったんだけど最後の方疲れ切っててミニオンだけ捨てたw
今考えたらヨッシー・アドベンチャー捨てればよかった。。。
時間的な余裕はあったんだけどまじで体力がついてかんかった😭ババア悲しい😭😭😭
ちなみにニンテンドー・ワールドは再入場不可になってて、エリア内のグッズショップにあるグッズのほとんどはエリア外にも売ってるんだけど、ほんの一部だけエリア内にしかないから迷ったらここで先に購入しておくのがおすすめ💪
キノピオカフェのご飯たち🍄 ご飯全部可愛かった🍄
夜ご飯は鬼滅の藤の花の食事処行った🎴
宇髄さんマーク🎆
持っていってよかったもの
- 日傘 ... 日焼け防止のため。これがないと待ち時間暑すぎて死ぬ。
- ハンディ扇風機 ... ないと暑すぎて死ぬ。
- モバイルバッテリー ... 基本スマホ触ってなかったんだけど、やっぱ写真撮ってるからか結構減りが早くて持っていってよかった
- 替えマスク ... コロナ対策。汗かいて気持ち悪いので一応持っていった
- 持ち歩き除菌スプレー(ジェル) ... コロナ対策。至るところにおいてあったんだけど食べる直前に使う用
持っていかなくてよかったもの
公式アプリについてはマップ確認できるんだけどマップに載ってる情報が少なすぎて全然使いもんにならんかったw
現在地が確認できるのは便利なんだけど、マップ上にエリア名?とかが載ってないから結構使いにくい
結局パーク内にある紙のマップの方使ってた
エクスプレス・パス使わずに行く人は待ち時間確認用にいいかも?
|
|
Composer のパッケージを作成した🎉
前からやってみたいと思いつつ後回しにしていた。。。
文字列をLeet文字に変換するっていう使い所がないパッケージだけど作れたことに満足:)
<?php use Leet\Leet; Leet::generate('shinazugawa sanemi') // 5h1n42u64w4 54n3m1
今は数字への変換しかできないけど記号への変換も今後対応する予定
そして Travis CI 童貞をやっと捨てた
いまいち使い方をよくわからんまま使ってるけどテスト通ってるのでヨシ!
Laravel の Eloquent ORM でサブクエリを作る
日付単位で number の合計が10以上のレコードのみを抽出する
データ
id | target_date | number |
---|---|---|
1 | 2021-09-01 | 1 |
2 | 2021-09-02 | 2 |
3 | 2021-09-01 | 3 |
4 | 2021-09-03 | 4 |
5 | 2021-09-04 | 4 |
6 | 2021-09-11 | 2 |
7 | 2021-09-06 | 5 |
8 | 2021-09-12 | 23 |
9 | 2021-09-12 | 10 |
10 | 2021-09-23 | 20 |
SQL
SELECT * FROM samples INNER JOIN( SELECT id, SUM(number) AS number_sum FROM samples GROUP BY samples.target_date ) AS samples1 ON samples1.id = samples.id WHERE number_sum >= 10;
これを Laravel の Eloquent を使ってサブクエリで書く
<?php $subQuery = Sample::selectRaw('sum(number) as number_sum') ->addSelect('id') ->groupBy('target_date'); Sample::joinSub($subQuery, 'samples1', 'samples1.id', 'samples.id') ->where([['number_sum', '>=', '10']]) ->get(['samples.id', 'target_date', 'number_sum']);
※ joinSub
は Eloquent じゃなくて QueryBuilder の機能だった
結果
id | target_date | number_sum |
---|---|---|
8 | 2021-09-12 | 33 |
10 | 2021-09-23 | 20 |
参考
株式会社エイルシステムではWebエンジニア・モバイルアプリエンジニアを募集しています。
実務経験がなくてもOKです。ご興味のある方は弊社HPよりご連絡ください。