ホーム > 技術系

技術系のアーカイブ

Node.jsについて理解が少し進んだ

今や様々なところで使われているNode.js。

そもそもこれが何なのか、今ひとつ理解できていない(使ってはいるものの、イメージが沸かない)状態だったのですが、ようやく理解が進みました。

それはどういうことかといいますと、「特定のディレクトリ以下に閉じ込めたJavascript実行環境」です。

どういうことかと、Javascriptのライブラリなどを一式準備するとき、必要となるライブラリなどが一式ありますが、それが、サーバ全体で共有するようなイメージだと、プロジェクトによって、必要なライブラリやバージョンが異なったりするため、競合が起こり、管理が大変になります。

それが、特定のディレクトリ以下に一式をすべてまとめられて単位で区切られていれば、プロジェクトごとにバージョンが異なっていても競合を起こすことはありません。

それを管理するのが「npm(node package manager)」です。

phpでいうcomposerみたいなかんじですね。

linuxの場合、yumでパッケージ管理をしていると、サーバ全体のライブラリが更新されたりしますが、npmの場合、特定のディレクトリ(npmを実行した環境)以下に全てまとめられ、それは主にプロジェクトごとに作成されます。

このことが当たり前っちゃ当たり前ですが、npmを実行してもバックグラウンドで何が実行されているかが分かりにくいため、ようやく理解することができました…。

nginx起動時のエラーの対処メモ

使っているサーバがkusanagiなのですが、nginxを起動時にエラーではないのですが、謎のwarningが出たのですが、原因について調査したのでメモです。

実行しようとしたコマンド

kusangi nginx

※ kusanagiでの、nginxの再起動コマンドです。

表示されたワーニング

kusanagi nginx
Nginxを使用します。
nginx: [warn] conflicting server name "default_server" on 0.0.0.0:80, ignored
nginx: [warn] conflicting server name "default_server" on 0.0.0.0:443, ignored
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
完了しました。

nginxの再起動自体は完了していますが、ワーニングが発生しています。

問題の場所がどこかが分からないんですよね…

解決した方法

cd /etc/nginx/conf.d

使っているサーバで、nginxの設定ファイルがあるディレクトリまで移動します。

_httpd.conf

というファイルがあり、中身を見ると

 ## default HTTP
  2 server {
  3     listen       80;
  4     server_name  default_server;

となっています。

_ssl.conf

というファイルがあり、中身を見ると

## default SSL
  2 server {
  3     listen       443 ssl;
  4     server_name  default_server;

となっています。

このdefault_serverというのが、ワーニングが出ている原因になっているようです。

考えたところ、この_httpd.confと、_ssl.confという設定ファイルは、読み込まれているものの無視されているようなので、ファイルをバックアップだけ取って、削除しました。

その後、nginxを再度再起動したところ

[[email protected] conf.d]# kusanagi nginx
Nginxを使用します。
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
完了しました。

今度はOKでした。

サーバ上のサイトも問題なく見れました。

何かの際に、不要な上のファイルが生成されて残っていたようで、削除することでワーニングが出なくなりました。

※ 同じ現象で対応される場合は、バックアップだけはきちんと取っておくことを推奨します。

ローカルのMAMP環境でのlaravelのmigrate時MySQL接続エラーに対処

MAMP環境で、Laravelでphp artisan migrateを実行したところ、以下のエラーが出ました

No such file or directory (SQL: select * from information_schema.tables where table_schema = ○○○ and table_name = migrations and table_type = ‘BASE TABLE’)

データベースの接続を.envファイルには設定できています。

調べてみると、/config/database.phpにsocketの追加が必要なようです。

MAMPでは、ソケットが以下の設定になっていました。

Socket/Applications/MAMP/tmp/mysql/mysql.sock

これを、/config/database.phpに追記します。

'mysql' => [
            〜省略〜
            'unix_socket' => env('DB_SOCKET', '/Applications/MAMP/tmp/mysql/mysql.sock'),
       〜省略〜
]

上記に修正後、再度 migrationを実行すると、今度は問題なく実行することができました!

Vue3で単一ファイルコンポーネントにpropsで値を受け渡す方法

Vue3で、単一ファイルコンポーネントにpropsで値を受け渡す方法についてのメモです。

親コンポーネント側の記述

下記では、Controllerから埋め込んだidという変数を、子コンポーネントのTestComponentに渡しています。

<div id="app">
    <test id="{{ $id }}"></test>
</div>

子Component側の記述

子Component側が、受け渡された値を使用するには、propsで名前を指定する必要があります。

<template>
    <div>親コンポーネントから渡された値:{{ id }}</div>
</template>

<script>
    module.exports = {
        props: ['id'],
        data() {
            return {
                ''
            }
        },
    }
</script>

laravel8のVueをVue2からVue3にバージョンアップした

作っていたサイトのLaravelと使っていたVueのバージョンが2系だったのから3系にバージョンアップしました。

以下、手順についてのメモです。

Vueのバージョンの確認方法

プロジェクトフォルダで

npm list vue

[email protected]

2系な模様。これを3系に上げたい

package.jsonの編集

プロジェクトフォルダのpackage.jsonを編集します。

まずは編集前に、package.jsonをバックアップ後、以下の記述を削除


"vue": "^2.6.12",
"vue-loader": "^15.9.6",
"vue-template-compiler": "^2.6.12"

Vue3のインストールを実行

Vue3のインストールをnpmで実行します。

npm install -save-dev [email protected]

その後、再び vue のバージョンを確認

npm list vue

[email protected]

Vue3系に上がってる!

num run dev を実行。

変なエラーが出る。丁寧に以下のコマンドを実行しろということ。

npm install @vue/compiler-sfc [email protected]^16.1.0 –save-dev –legacy-peer-deps

上記を実行後、npm run devを実行。

問題なく実行できました。

そして、あとはアプリ側のVueのソースを、Vue3のプログラムに書き直します。

これは、ここのサイトを参考にさせていただきました。

Vue 3 を Laravel 8で使う方法(npm) | console dot log

これで、うまく行った・・・かと思いきや、ローカルではうまく動いたのに、本番環境ではテストプログラムが動作しません。

散々調べた挙げく、原因が分かりました。

CDNのキャッシュ

Laravel + Vueでは、npm run devで、app.jsをビルドするのですが、

これが、古いファイルがCDNにキャッシュされてエラーになっていたのが原因でした。

CDNのキャッシュをクリアすることで、無事に表示されることになりました。

と、ここまででようやくLaravel8 + Vue3で基本的なプログラムが表示できたのですが、スタート地点に立つだけでも大変ですね・・・。

Laravel+Vueで、Componentを更新しても反映されない

Laravel8+Vueでサイトを構築中、VueのComponentのファイルを更新しても、何故か画面に反映されなくて困りました。

具体的にいうと、デフォルトでLaravelでVueを有効にすると入ってくるExample Componentがあります。

ファイルの場所は、Laravelのルートディレクトリ以下の

/resources/js/components/ExampleComponent.js

があります。

このファイル内容をテストで更新してみたのですが、画面に反映されないのです。

謎…。

で、調べてみたところ、ルートディレクトリで

npm rum dev

をしないと更新されないということ。

なんだそれ、分かりにく・・・

しかし試しに実行で、エラー

Error: Cannot find module ‘../package.json’

で、調べてみると、node_modueを再インストールしてみたらいいということです。

rm -rf ./npm_modules

npm install

で、node_moduleを再インストールで、

npm rum dev を実行

今度はエラーがでず・・・

で、サイトを見に行くと、、、、

更新されていない orz

で、ブラウザのキャッシュを削除すると・・・・

更新されました!!

というわけで、分かりにくかったですが、何とかComponentを更新するところまではたどり着きました。

ただこれだけのことで、最初は大変・・・

kusanagiでMariaDBのバージョンを10.1から10.3に上げた

使っているサーバで、Laravelでサイトを構築しようと思ったら、migrationでエラー。

原因としては、mysqlのバージョンが最新でないことが原因だそうです。

使っていたのがMariaDB10.1で、MySQL5.6相当

MariaDBを最新の10.3に上げることができれば、MySQLの5.7に相当するようです。

アップした方法

以下のサイトに解説がありました。

KUSANAGI バージョンアップ情報 8.5.0-1 | KUSANAGI

yum update -y
kusanagi upgrade mariadb 10.3

上記を実行する前に事前にバックアップは取っておいてねということなので、取っておきました。

参考にしたサイトは以下です。

MariaDBを10.3にアップグレードする際の手順と注意事項 | 己で解決!泣かぬなら己で鳴こうホトトギス

mkdir /tmpMDB10.1
mkdir /tmpMDB10.1/my.cnf.d
mkdir /tmpMDB10.1/postfix
mysqldump -u root -p --all-databases > /tmpMDB10.1/all_db_backup.sql
cp -r -a /etc/my.cnf /tmpMDB10.1/my.cnf
cp -r -a /etc/my.cnf.d/* /tmpMDB10.1/my.cnf.d/
cp -r -a /etc/postfix/* /tmpMDB10.1/postfix/

上記の方法でバックアップを行った後、バージョンアップを実行しました。

バージョンアップは数分時間がかかったものの問題なく終了し、各種サイト(WordPress、Laravel)はいずれも問題なく動いていることを確認しました。

また、目的であったLaravelのmigrationも問題なくできるようになりました。

cakephp3の日時のYMDフォーマットについて

cakephp3で、データベースから取得した日時などのオブジェクトのデータを画面に出力する場合に、YMD形式のフォーマットに変換するケースがありますが、yは大文字か小文字か、など微妙なところでよく分からなかったのでメモです。

例えば、以下のように使います。

$now = Time::parse('2014-10-31');
// '2014-10-31 00:00:00' と出力します。
$now->i18nFormat('yyyy-MM-dd HH:mm:ss');

cakephpで使われているYMDフォーマットについては、以下のページに詳しく解説がありました。

Formatting Dates and Times | ICU Documentation

上記のページから抜粋します。

SymbolMeaningPatternExample Output
Gera designatorGGG, or GGG
GGGG
GGGGG
AD
Anno Domini
A
yyearyy
y or yyyy
96
1996
Yyear of “Week of Year”Y1997
uextended yearu4601
Ucyclic year name, as in Chinese lunar calendarU甲子
rrelated Gregorian yearr1996
QquarterQ
QQ
QQQ
QQQQ
QQQQQ
2
02
Q2
2nd quarter
2
qstand-alone quarterq
qq
qqq
qqqq
qqqqq
2
02
Q2
2nd quarter
2
Mmonth in yearM
MM
MMM
MMMM
MMMMM
9
09
Sep
September
S
Lstand-alone month in yearL
LL
LLL
LLLL
LLLLL
9
09
Sep
September
S
wweek of yearw
ww
27
27
Wweek of monthW2
dday in monthd
dd
2
02
Dday of yearD189
Fday of week in monthF2 (2nd Wed in July)
gmodified julian dayg2451334
Eday of weekE, EE, or EEE
EEEE
EEEEE
EEEEEE
Tue
Tuesday
T
Tu
elocal day of week
example: if Monday is 1st day, Tuesday is 2nd )
e or ee
eee
eeee
eeeee
eeeeee
2
Tue
Tuesday
T
Tu
cstand-alone local day of weekc or cc
ccc
cccc
ccccc
cccccc
2
Tue
Tuesday
T
Tu
aam/pm markerapm
hhour in am/pm (1~12)h
hh
7
07
Hhour in day (0~23)H
HH
0
00
khour in day (1~24)k
kk
24
24
Khour in am/pm (0~11)K
KK
0
00
mminute in hourm
mm
4
04
ssecond in minutes
ss
5
05
Sfractional second – truncates (like other time fields)
to the count of letters when formatting. Appends
zeros if more than 3 letters specified. Truncates at
three significant digits when parsing.
S
SS
SSS
SSSS
2
23
235
2350
Amilliseconds in dayA61201235
zTime Zone: specific non-locationzzz, or zzz
zzzz
PDT
Pacific Daylight Time
ZTime Zone: ISO8601 basic hms? / RFC 822
Time Zone: long localized GMT (=OOOO)
TIme Zone: ISO8601 extended hms? (=XXXXX)
ZZZ, or ZZZ
ZZZZ
ZZZZZ
-0800
GMT-08:00
-08:00, -07:52:58, Z
OTime Zone: short localized GMT
Time Zone: long localized GMT (=ZZZZ)
O
OOOO
GMT-8
GMT-08:00
vTime Zone: generic non-location
(falls back first to VVVV)
v
vvvv
PT
Pacific Time or Los Angeles Time
VTime Zone: short time zone ID
Time Zone: long time zone ID
Time Zone: time zone exemplar city
Time Zone: generic location (falls back to OOOO)
V
VV
VVV
VVVV
uslax
America/Los_Angeles
Los Angeles
Los Angeles Time
XTime Zone: ISO8601 basic hm?, with Z for 0
Time Zone: ISO8601 basic hm, with Z
Time Zone: ISO8601 extended hm, with Z
Time Zone: ISO8601 basic hms?, with Z
Time Zone: ISO8601 extended hms?, with Z
X
XX
XXX
XXXX
XXXXX
-08, +0530, Z
-0800, Z
-08:00, Z
-0800, -075258, Z
-08:00, -07:52:58, Z
xTime Zone: ISO8601 basic hm?, without Z for 0
Time Zone: ISO8601 basic hm, without Z
Time Zone: ISO8601 extended hm, without Z
Time Zone: ISO8601 basic hms?, without Z
Time Zone: ISO8601 extended hms?, without Z
x
xx
xxx
xxxx
xxxxx
-08, +0530
-0800
-08:00
-0800, -075258
-08:00, -07:52:58
'escape for text'(nothing)
' 'two single quotes produce one' '

cakephp3でorder byにcase文を使用する

cakephp3で、order by 句にcase文を使用したいケースがあったので、メモです。

今回実装したかったのは以下の内容です。

特定のテーブルから、

(1) あるカラムがAまたはBのグループを先頭に持ってきて

(2) その後に(1)でないグループを表示

(3) (1)(2)が同じ条件場合は、別のカラムの値降順で表示

以下のような実装で実現できました。

// モデルでの実装の例
$query = $this->find();

// CASE WHEN ((カラム名 = A) or (カラム名 = B)) THEN 1 ELSE 2 END
$case = $query->newExpr()
                ->addCase(
                    $query->newExpr()->add([
                        'OR' => [
                            'カラム名' => A,
                            'カラム名' => B
                        ]
                    ]),
                    [1, 2],
                    ['integer', 'integer']
                );

$query->order([
    $case,
    カラム名 => 'DESC'
]);

/* これで、
select * from table order by (CASE when (カラム名 = A or カラム名 = B) THEN 1 ELSE 2 END), カラム名 DESC
と同じものが実行できました
*/

【CakePHP】Log::debugが出力されない解決方法

CakePHP3では、デバッグでログ出力するのに

use Cake\Log\Log;

LOG::debug(“出力したい内容”);

を使うことで、デバッグログファイルにログを出力することができます。

しかし、これを自分の開発環境で使ってみたところ、ログが出力されない現象が発生することがあり、困っていました。

調べたところ、出力できるようになったのですが、原因としては、

/config/app.php 内の

'debug' => [
            'className' => 'Cake\Log\Engine\FileLog',
            'path' => LOGS,
            'file' => date("Ymd").'_debug',
            'url' => env('LOG_DEBUG_URL', null),
            'scopes' => false,
            'levels' => ['notice', 'info', 'debug'],
        ],

で、scopes = true になっていたのが原因でした。

これを scopes = false にすることで、ログが出力されるようになりました。

ぱっと見では、trueにすることで出力されるんではないかと思いますが、trueだと逆に出力されないということですね。

Laravel7をインストールした記録

Laravel7をインストールするのに、エラーが出たりして微妙に苦労したのでメモ。

環境

CentOS

php7

以前別のプロジェクトで同じサーバにLaravelを入れていた(5系)

まずは、手順に従って、Laravelをインストールしようとした

composer global require laravel/installer

するとエラーが

SHA384 is not supported by your openssl extension, could not verify the phar file integrity

調べてみると、composerのバージョンが古いためにLaravel7系の場合は合わないらしい。

composerの最新のバージョンは1系、Laravelは7系。

これが駄目ってことか。

というわけで、composerのバージョンを最新版の2系にバージョンアップ。

この記事を参考にcomposerの再インストールを実施しました。

composerのダウンロードとインストールは、公式の記事を参考にしたらいいと思います。

結果、composerのバージョンは最新の2系になりました。

composer -V

Composer version 2.0.9

そして、再度Laravelのインストールコマンドを実行

すると、今度はまた別のエラーが

Installation failed, reverting ./composer.json and ./composer.lock to their original content.

エラーの内容は、最初見てよくわからなかったのですが、最終的に分かったこととしては、今回実行しようとしている

composer global require laravel/installer

というコマンドは、Laravelのインストーラーを作成するコマンドであって、それが同じサーバにすでに作成していたLaravelのプロジェクト(5系)の作成時にすでに設置していたLaravelのインストーラーがあり、その設定ファイルのcomposer.jsonとcomposer.lockと内容が競合しているというような意味だったみたいです。

上記の過去プロジェクトはもうすでに更新してないサイトだったのもあり、過去に作成したインストーラーを、一旦リネーム(削除するのは何か怖かったのでリネーム)することで、上手く設置することができました。

Laravelのインストーラーは、サーバの設定により異なりますが、自分の環境の場合は

/home/.config/

以下がそうだった(それ以下にLaravelのインストーラーが入っていた)ので、上記フォルダをリネーム後にサイド実行することで、上記ディレクトリが新しく作成され、そこにLarvel7に必要だったcomposer.json、composer.lockも新しく作られました。

そして、Laravelのインストールを実行

laravel new プロジェクト名

しかし、以下のエラーが・・・

bash: laravel: コマンドが見つかりません

調べてみると、Laravelのインストーラーへのパスが通ってないみたいで、ホームディレクトリの.bash_profileにパスを設定しないといけないらしい。

しかし、確認するとすでにパスの記述がある・・・。だとするとなぜ?

source .bash_profile

をすることで読み込まれたみたいで、無事Laravelのプロジェクトを作成することができました。

Laravelのドキュメントルートにアクセスするとエラーが

The stream or file “/storage/logs/laravel.log” could not be opened in append mode: failed to open stream: Permission denied

調べるとアクセス権がないとかうことみたいで、

chmod -R 777 storage

で解決。755でいけるとか書いてたけどどうにもならず、777にしたらいけました。

[Cakephp3】validationとbuildRulesの違いや使い分けについて

Cakephp3のValidationとBuildRulesについての記事です。

Cakephp3ではフォームのバリデーション(エラーチェック)はモデルで行われますが、エラーチェックの方法に、validationと、BuildRulesの2パターンがあります。

この違いについて解説したいと思います。

まずvalidationについてですが、基本的にmodelのvalidationDefaultメソッドの定義していきます。一般的なエラーチェックはこちらに定義していくパターンが多いと思います。

BuildRulesは、validationメソッドとは別に定義していきます。

通常のvalidationとは記述方法が微妙に違うので、そこは公式サイトを見て確認してください。

それで、この2つの何が違うのかについてですが、バリデーションが実行されるタイミングです。

通常のvalidationは、Controller側でnewEntityやpatchEntityを実行するタイミングで行われます。

これに対して、BuildRulesは、モデルからsaveメソッドを実行するタイミングで行われます。

この2つのどう使い分けるかというと微妙なところがあって私も完全には理解してないのですが、例えば日付を比較するようなエラーチェックを入れる場合、Build Rulesのほうに追加すると便利です。

なぜなら、日付を比較するようなエラーチェックの場合、そもそも入力値が日付でなかったりする場合、エラーチェックの処理の途中で日付でないのでエラーになってしまったりして、データが「日付である」という前提を担保することが難しいわけです。

これを、Validationのほうに日付のエラーチェックを定義しておいて、日付データの比較はBuiled Rulesのほうに定義しておけば、日付でない場合はpatchEntityのタイミングでエラーになってsave時のBuild Rulesまで処理が進まないので、内部的な処理で日付がどうこうみたいな処理を書く必要がなくなります。

他にもあるかもしれませんが、私の理解ではそんなところです。

PostgresSQLのTriggerで、insertする値をINSERT BEFOREで計算する

関わっていた案件で、PostgresSQLのTriggerを使って、Insertする特定のカラム値を、TriggerのInsert Beforeを使って計算して挿入するというケースがありました。

Qiitaの以下の記事がわかりやすかったです。

PostgreSQLでトリガを作成し、同一テーブル内に値を追加する

https://qiita.com/grassfield/items/60fad9c1d4a8d205bff3

CREATE OR REPLACE FUNCTION culc_totalworktime() RETURNS trigger AS $BODY$
BEGIN
  NEW.勤務時間 := NEW.終了時刻-NEW.開始時刻-NEW.休憩時間; -- 解説
  RETURN NEW;
END;
$BODY$ LANGUAGE plpgsql VOLATILE COST 100;
ALTER FUNCTION culc_totalworktime() OWNER TO postgres;

上記のようなかんじで値を返すトリガを作成して

CREATE TRIGGER totalworktime_trg
BEFORE INSERT OR UPDATE ON 勤務実績
FOR EACH ROW EXECUTE PROCEDURE culc_totalworktime();

上記のようにINSERT BEFOREでトリガを呼び出してやれば、カラムに計算された値が挿入されました。

kusanagi+nginxでall-in-one wp migrationのインポートが100%で止まる対処法

kusanagiのWordPress実行環境で、all-in-one wp migrationを使ってサイトのインポートをしていたところ、100%まで進んだところで止まってしまい、それ以上進まなくなるという状況になってしまいました。

原因について調べてみたのですが、まずはサーバのエラーログを見てみたところ、以下のようなエラーが出ていました

client intended to send too large body: 65213411 bytes, client

これは、postしたデータサイズが設定を超えていたのではじかれているという内容みたいです。

サーバはnginxを使っていたので、以下のように設定を変更しました

該当のサーバのnginxの設定ファイル〇〇.confを編集します

client_max_body_size 16M;

調べたところ、デフォルトでは自分が使っているサーバでは上記の設定だったので、ひっかかってエラーになっていたみたいです。

client_max_body_size 100M;

上記のように上限を変更し、nginxを再起動することで無事インポートできるようになりました。

CakePHPのFlashComponentについて

CakePHPのFlashComponentについての解説です。

公式サイトでは以下のページに解説があります。

フラッシュ

公式サイトの解説が分かりにくいので、自分流の解釈ですが、FlashComponentは、特定のメッセージをサイトで表示するのに使います。

Sessionに表示するデータを保存して、画面遷移後に表示することが可能です。

普通にエラーメッセージを表示する場合と比較すると、表示するメッセージを保存して、画面遷移後の表示に使う事ができる特徴があります。

使い方

Controllerで以下の定義

public function initialize() {

parent::initialize();
$this->loadComponent(‘Flash’); // Include the FlashComponent

}

表示したいデータを以下のように使う。

//成功した場合出力。リダイレクト後のページで表示される

successやerrorなどのテンプレートは、/sec/Template/Element/Flash以下にあるので追加や編集も可能。

$this->Flash->success(__(‘Your article has been saved.’));

$this->Flash->error(__(‘Unable to add your article.’));

テンプレートの以下の記述の場所にFlashメッセージが表示される

<?= $this->Flash->render() ?>

CakePHPのLoadComponentについて

CakePHPのLoadComponentについての解説です。

LoadComponentメソッドは、Controller内で実行することができ、あらかじめCakePHPの準備されているComponentを呼び出すことができます。

Componentとは、機能のようなもので、メソッドのかたまりのようなものです。

一般的なプログラムでのライブラリ読み込みのようなものと考えればよいでしょう。

Componentをコントローラで使用する場合は、initializeメソッドの中でLoadComponentを使って該当のComponentを呼び出します。

読み込むことができるComponentには以下の種類があるので、詳細は以下のそれぞれの記事を参照とのことです。

CakePHPのaddBehaviorについて

CakePHPのaddBehaviorメソッドについての解説です。

CakePHPのチュートリアルを進めていると、Tableクラスで以下のような記述があります。

class ArticlesTable extends Table
{
    public function initialize(array $config)
    {
        $this->addBehavior('Timestamp');
    }
}

上記の意味がわからなかったのですが、調べてみると以下のような記述がありました。

デフォルトの設定は以下のようになっています:

  • 新しく Entity を保存するとき、 created と modified に現在の日時を設定します。
  • Entity を更新したとき、 modified に現在の日時を設定します。

上記のように宣言することで、対象のテーブルの項目「created」と「modified」が、データが作成されたときにタイムスタンプが更新されるようになる他、データが更新されたときにmodifiedの項目が自動で更新されるようになるということです。

AWSで何も使ってないのに課金される問題に対処

AWSの試用期間中で無料期間中にいろいろと試しているのですが、インスタンスを使用後に削除したのに、請求で料金がチャージされているのが謎でした。

ダッシュボードで利用状況を確認しても、利用しているEC2インスタンスは存在していないのに、EC2インスタンスに対して料金がチャージされていっているのです。

原因について調べていたところ、原因が判明しました。

AWSのダッシュボードの右上で、AWSのロケーション(米国東部とかいろいろある)を変更できますが、現在のロケーションでなく、別のロケーションに存在していました。

そのため、現在のダッシュボードに利用しているリソースが存在していないけど料金がチャージされているという場合、ロケーションを1つずつ変更しつつチェックして確認することで見つかる場合もあると思います。

Vue.jsで、v-forディレクティブの:keyの意味

Vue.jsで、Vueオブジェクトのデータをループさせるときに、v-forディレクティブを使用します。

<li :v-for=”変数 in Vueオブジェクトのデータ名”>{{ 変数.データ名 }}</li>

上記のような感じで使いますが、いろいろなサイトでコードのサンプルを見ていて、上記のような書き方だけのときもあれば

<li :v-for=”変数 in Vueオブジェクトのデータ名” :key=”変数.id”>{{ 変数.データ名 }}</li>

のように、:keyがついている場合とついていない場合があります。

何のために :key がついているのか調べてみたのですが、Vueの機能でDOMを書き換えた時に、keyを指定していないと、順番が変わってしまうことがあるそうで、つけておくことで並び順を保持できるそうです。

ajaxについての勉強メモ

ajaxについての勉強メモです。

ajaxとは

ajaxとは、javascritを使って、ページを非同期に更新する仕組みのことです。

とはいえ、ajaxという言葉を使わなくても、javascriptは、普通にスクリプトを実行することで、イベント発生時(マウスオーバーやクリック時など)、ページの内容を書き換えることは可能です。

では、ajaxとはその通常のjavascriptの仕組みと何が違うのでしょうか。

それは、ウェブページから、動的に現在のページでない他のページからのリソースを要求し、その結果をページに反映できるという点です。

たとえば特定の要素をマウスでクリックしたときに、ajaxの仕組みを使って、phpファイルを実行し、その帰ってきた結果を解析してページ内に反映させることができます。

この仕組みを実現するためにjavascirptに実装されているAPIの機能がajaxです。

そのことを、例えばフォームをサブミットしたりページをリロードしたりせずに実行できる仕組みと考えればよいでしょう。

javascriptの$(function(){})の意味について解説

javascriptのソースコードを見ていると、よく以下のような記述があります。

$(function(){})

これを、javascript初心者の人が見ると

???

となりますが、この意味について解説したいと思います。

まず、javascriptでは、関数をオブジェクトとして定義することができ、そのまま関数名を定義せずに変数に代入してオブジェクトにすることができる。

この事は知っている人が多いと思います。

また、javascriptは、即時関数という機能があって、定義した関数をその場ですぐに実行することができます。

これは、

(function() { 実行内容 } ())

このような書き方をします。

上記のような書き方をすることで、実行内容をその場で実行することができるわけです。

しかし、 タイトルにある

$(function(){ 実行内容 })

は、上記の記述とも微妙に違います。

これは、jQueryを使用している場合の記述です。

ページのDOMツリーの読み込みが完了した後に、実行内容を実行するということで、javascirptの通常の即時関数と似ていますが、JQuery使用時固有のものです。

Laravelでマスタデータ(key-valueデータ)をどう管理するか

Laravelで、フォームを作る時に、例えば選択ボックスがあって、そこから値を取り出したい場合があります。

例えば、性別[男、女]とか、都道府県[北海道〜沖縄]とか、カテゴリ[〜、〜]とか色々と考えられます。

それらのデータは、しょっちゅう変更があるもので、複雑なものであればデータベースにテーブルを作ってそこから引っ張ってくる方法もあるのですが、例えば男、女のような小さいデータセットであれば、わざわざそれをするほどでもないというか、いちいちテーブルを追加してデータをセットするというのが、Laravelの場合マイグレーションを通さないといけなかったりと色々と面倒です。

その場合に便利なやり方ですが、configに追加するのが楽です。

以下のページにやり方が書いてありました。

Laravelで都道府県のプルダウンメニューを作ってみる

一応手順についてメモしておきます

1.config以下に好きなファイル名で作成

都道府県であれば、per.phpのようなファイル名をconfig以下に作成して保存します。

return array(
  '1' => '北海道', 
  '2' => '青森県', 
省略
  '46' => '鹿児島県', 
  '47' => '沖縄県'
);

ちなみに、configのキャッシュが残っていると反映されないので、ファイルアップ後は以下のコマンドが実行必要です。

php artisan config:cache

上記の例では、pref.phpには一つしか配列が定義されていないですが、
複数定義したい場合は以下のように多次元配列でも設定が可能です。

return [
    "sex" => [
        "1" => "男",
        "2" => "女",
    ]
];

上記のように設定しても、後で問題なくアクセスできます。

コントローラーで取得→テンプレートに表示、または直接bladeに表示

作成したファイルは、config(ファイル名)で、いつでも参照して取得可能です。

コントローラーで取得してからテンプレートに表示する方法

public function sample() {
  $prefs = config('pref');
  return view('sample')->with(['prefs' => $prefs]);
}

直接テンプレートに記述する

以下のように直接取得することも可能です。

<select name="_pref">
  @foreach(config('pref') as $index => $name)
    <option value="{{ $index }}" @if(old('_pref') == $index) selected @endif>$name</option>
  @endforeach
</select>

多次元配列の場合は以下のようなかんじです。

例えば、config/common.phpに

return [
    "sex" => [
        "1" => "男",
        "2" => "女",
    ]
];

上記のような定義を例えばcommon.phpにした場合、以下のように記述できます。

<select name="sex">
    @foreach(config('common.sex') as $index => $value)
        <option value='{{ $index }}' @if(old('sex') == $index) selected @endif >{{ $value }}</option>
    @endforeach
</select>

 

Javascriptのクロージャについて解説

Javascriptのクロージャについての解説です。

Javascirptのクロージャとは何か

Javascriptのクロージャとは何か。

私の理解では

関数の中で関数を定義したもの

という理解です。
(あくまで私の理解です)

まず、基本的なところで

・ 関数を定義すると、関数内で定義した変数は関数外部から参照できない

という性質があります。
これはほとんどの人が知っていると思います。

例えば

function func() {
  var value = 1;
  console.log(value);
}
func(); // 1
console.log(value); // undefined

上記のようなプログラムの場合、関数を実行した場合、実行結果は
1になりますが、関数内の変数を出力した場合、
参照できていません。

function func() {
  var value = 1;

  function innerFunc() {
    value++;
  }
  innerFunc();
  console.log(value); // 2
}
func();

上記のようなプログラムの場合、関数の内部でinnerFuncという関数を定義して関数内で実行しています。
このinnerFUncをクロージャといいます。

innerFunc内では、外側の関数(エンクロージャ)で定義している
変数valueを呼び出していますが、その値を参照できているだけでなく、
更新することができます。

つまり、javascriptでは、関数の中で定義された関数の仕様は通常の
関数と、その外側の領域と違い、その関数内部で変数を参照したり、更新
したりできるのです。

このような仕組みを利用して、関数を定義する際に使用することがありますので、
性質として覚えておくと良いでしょう。

どのようなときに使うのか?

上記のクロージャの仕組みを使うと、関数内の変数の値を維持したまま、
その関数内の値を更新するプログラムをかけたりします。

例えば、関数内で定義した変数を、その関数内の関数を定義して返すような
関数にすることで、関数の外で変数を定義して更新したりしなくても、
関数を実行する度に関数を実行できたりするわけです。

書き方によってはクロージャを使わなくても実装できる場合もありますが、
コードがよりシンプルになったり、便利なケースがあるようです。
(未だにそういう場面に遭遇したことがないので分からない・・・)

JavascriptのSymbolについて解説

JavascrotのSymbol機能は、もともとJavascriptに存在していた機能ではありません。

ECMAScript6 (ES6, ES2015) で導入された機能です。

使い方

var a = Symbol();

このように使うことができます。

こうすることで、aには他の値を被らない値(具体的な数値ではない)が、自動生成されて代入されます。

例えば

var a = Symbol();
var b = Symbol();

上記のように定義しても、aとbの値は異なった値になります。

値の型はtypeofをすると「symbol」と表示される、独自の型となっています。

何のために存在しているのか

何故このような機能が追加されたのかというと、
自分でユニークな値を設定したつもりでも、他の値と予期しない形で衝突することが
あるため、そのような状況を防ぐためです。

PHPの無名関数(クロージャ)について

PHPの無名関数(クロージャ)についてのまとめです。

無名関数とは

無名関数とは、関数規則に沿って命名を必要とせず定義できる関数です。

function(引数) {
処理内容;
}

といった形で使用できます。

例えば

$func = function(引数) {
処理内容
}

といった形で定義した場合、この$funcは、ラムダ関数とも呼ばれます。

$a = $func(引数);

このような形式で、使用する場所で呼んで使用できます。

無名関数を使用するメリット

無名関数は概念的には関数と同じなので、無名関数にせず関数として定義して呼び出しても同じなのですが、
普通の関数を定義無名関数を使用することにより、その場限りで呼び出す処理の場合は、関数名を他の関数名と衝突しないで済む、プログラム全体が複雑にならないといったメリットがあります。

無名関数内の処理に外部の変数を使用したい場合

プログラムによっては、無名関数の中で使用するプログラムに、無名関数の外の変数を使用したい場合があります。

無名関数は関数なので、引数にしている変数以外の外部の変数は内部の処理には適用されません。

しかし、use文を使うことでその問題は解決できます。

$func = function(引数A) use(変数B) {
処理内容;
}

このように無名関数を使用することで、処理内容で引数Aだけでなく外部の変数Bも使用できます。

Laravelのbladeテンプレートで配列の要素の存在を判定する方法

Laravelのbladeテンプレートで、配列をforeachなどの構文でループで回すことはよくありますが、配列の要素が存在するかどうかをテンプレート上に記述したい場合があります。

その場合、以下のように記述できます。

@if(!$posts->isEmpty())

        

        @else

            

検索条件に合致する内容がありませんでした

@endif

上記の場合は、配列postsが空かどうかを判定し、空出ない場合はループ処理を記載しています。

配列にない場合はelse後の処理に記載しています。

Bootstrap4で、table-responsiveで横スクロールが出ないのに対処

Bootstrap4で、横長のtableにtable-responsiveクラスを適用して、はみ出させずに横スクロールさせようと思っていたのですが、何故かtable-responsiveを適用してもtableが横に飛び出したままで横スクロールが出現しませんでした。

書いていたコードは以下のような内容です。

-----

これで行けるはずなのですが・・・・

そしていろいろ試してみたのですが、原因がわかりました。

 ← 親要素のこれが原因
-----

原因としては、div class=”table-responsive”の親要素に、class=”row”が入っていました。

これを削除することで動作するようになりました。

修正後

 ← class="row"を削除
-----

TinyMCEを特定のtextareaに対して無効にする方法

TinyMCEを、特定のフォームに対して無効にする方法についての解説です。

TinyMCEは、簡単に入力欄にWYSIWYGを導入できるので便利ですが、
デフォルトの設定だと全てのtextareaにWYSIWYGが導入されてしまうため、WYSIWYGがついてほしくない
textareaはどうしたらいいのか分からず少し調べました。

TinyMCEのバージョンによって設定方法が異なると思うので、自分が使っているバージョン(4系)についてです。

TinyMCEを導入する際に、ヘッダの部分に以下のような記述があると思います。

tinymce.init({
            selector: "textarea",
            branding: false,

この箇所を、以下のように書き換えます

tinymce.init({
            selector: "textarea#mce",
            branding: false,

こうすることで、「textarea id=”mce”」となっているtextareaのみがTinyMCEの対象になります。

ちなみに、classでもいけます。

tinymce.init({
            selector: "textarea.mce",
            branding: false,

idだと、1つのテキストエリアしか対象にできないので、複数のテキストエリアを対象にしたい場合は、クラスで定義するのが有効です。

Laravelで「composer require doctrine/dbal」を実行でエラー「Installation failed, reverting ./composer.json to its original content.」の対処法

Laravelのマイグレーションで、カラム変更の機能を使う場合に、以下のエラーが発生しました

Changing columns for table “table” requires Doctrine DBAL; install “doctrine/dbal”.

テーブルのカラム変更をするにはdoctrine/dbalをインストールしろということ
公式サイトを確認したところ

composer require doctrine/dbal

をしないとエラーになるということで、実行。

すると、ここでもエラー

Installation failed, reverting ./composer.json to its original content.

インストールに失敗したので、composer.jsonを元に戻しましたということ。
もうちょっとエラーの内容を詳細に見てみます。

Your requirements could not be resolved to an installable set of packages.
あなたの要求は、インストール可能なパッケージのセットに対して解決できません

Problem 1
– The requested package laravel/framework (locked at v5.8.2, required as 5.7.*) is satisfiable by laravel/framework[v5.8.2] but these conflict with your requirements or minimum-stability.

要求されたパッケージはLaravel5.8.2系を必要としているので、あなたのLaravelのバージョンに対しては対応できません

ということ。

というわけで、Laravelnバージョンを5.8系にアップすることで解決できました。

まずは、composer.jsonを編集します。

“require”: {
“php”: “^7.1.3”,
“doctrine/dbal”: “^2.9”,
“fideloper/proxy”: “^4.0”,
//ここを変更
“laravel/framework”: “5.7.*”,→”laravel/framework”: “5.8.*”,
“laravel/tinker”: “^1.0”
},

ここが5.7系になっていたので、5.8系に変更します。

その後、composer update

これで、Laravelのバージョンが5.8系に変更され、その後

composer require doctrine/dbal

これで無事インストールできました。

Laravel5でフォームにWYSIWYGエディタを利用する

Laravel5のフォームを作っていて、textareaの入力欄にWYSIWYGエディタを導入してWordPressっぽくするというのを
試していたのですが、以下の記事を参考にして実装することができました。

Laravel5にWYSIWYGエディタを実装する方法 | Qiita

詳しくは上記の記事を参考にしていただければ簡単に実装できます。

手順としては、

1・TinyMCE をダウンロードして、サーバへアップロード

2・jbimages をダウンロードして、TinyMCEのpluginsフォルダへアップロード
(configファイルの画像の保存パスの変更と、該当フォルダに書き込み権限をつける必要あり)

3・実装するサイトのヘッダにjsファイルのincludeと、javascriptのコードを追記する

これだけで、至って簡単に実装することができました。

ただ、上記のQiitaの記事が若干古くなっていました。

この記事執筆時点(2019年3月)では、TinyMCEの最新バージョンが5系となっていたのですが、jbimagesは4系にしか対応していないので、TinyMCEの4系をサイトからダウンロードして使用する必要があります。(5系では動作しませんでしたが、将来的には対応しているかもしれません)

4系での設定方法は、以下のページに解説がありました。

JustBoil.me TinyMCE Images Plugin — A simple solution for uploading images in TinyMCE

ホーム > 技術系

フィード

ページの上部に戻る