月別アーカイブ 7月 2019

著者:杉浦

【Laravel】一プロセス内限定のSQLのキャッシュを作る

 ORMは便利ですが、何度も重複するクエリを発行しがちです。複数のモデルオブジェクトeachしてリレーション先を参照する時は特に危険です。どれくらい重複してるかは
 barryvdh/laravel-debugbar: Laravel Debugbar (Integrates PHP Debug Bar)
 などで調べるのが楽です。duplicatedとuniqueに分けてくれます。

 やり方の方針はクエリが発行される度にそのクエリに対応するキャッシュはあるかチェック、あるならばキャッシュを結果として取得、なければ実際に発行して結果を取得してキャッシュに保存、です。
 一つのクエリに使う場合は次です。

        $key = __FILE__.' '.__FUNCTION__.' '.__LINE__ .' '.$id;
        app()->offsetExists($key) ?: app()->singleton($key, static function () use ($id){
            return Member::where('id',$id)->get();
        });

 コードの場所と引数に関して一意になるキーを設定。クエリの結果をシングルトンに登録することによって、同じ場所が同じ引数で繰り返し呼ばれる際、同じクエリを発行することなく、Laravel内にバインドされたシングルトンを呼ぶようになります。変数なのでプロセスが終わったら揮発します。
 作った後しばらくして気づきましたがarrayドライバ(array型の変数内にキャッシュを保存する機能)でキャッシュ使った方がシンプルですね。
 全体のクエリに使う場合はDBのselect等データ取得時のリスナーに同じ処理を入れます。updateした時のリスナーにキャッシュ消す処理忘れるとバグの元になります。

  • この記事いいね! (0)
takahashi 著者:takahashi

VRoidモバイルで映画”サマーウォーズ”のOZを再現した3D空間が体験できるらしい。

最近、VR用HMDの普及やセンサー類の普及に伴い、バーチャルユーチューバー(Vtuber)や3Dアバター、仮想世界などの界隈が盛り上がってきています。

この流れの中、Pixivが 3Dアバターをより手軽に作成することを可能にするサービス、VRoidを公開しています。

VRoidとは – VRoid

創作にかかわるサイトや支援技術を開発するPixiv社ならではのサービスです。

そんなVRoidのサービスの一つ、VRoidMobileで、映画サマーウォーズの作中で出てくる仮想空間”OZ”のシーンで実際に使用された3Dオブジェクトをつかって遊ぶことができるステージ(?)が公開されているようです。

OZ on VRoid – VRoid

映画で使われた3Dオブジェクトを一般ユーザーが心行くまで見れるというだけでもワクワクですが、さらにそこに自作のアバターを登場されられるというのは、ファンにとってはたまらない内容ではないでしょうか。

最近になって実際にVR周りの技術が盛り上がってきて、映画に出てきたような技術が少しづつ現実になってきているのはとても感慨深いですね。

ちなみに、今日の21時から元ネタとなっているサマーウォーズがノーカットで放送されるようですので、興味のある方は是非。

  • この記事いいね! (0)
村上 著者:村上

【Excel】セルに値が入力されているかを判定する方法

久しぶりに使おうとして関数名を忘れてしまっていたので、備忘録として。
Excel で セルが入力されているか、もしくは空なのかを判定する方法です。
使用するのは「ISBLANK」という関数です。

参考にさせていただいた記事はこちらから。

エクセル ISBLANK 関数:セルが空白か判定する
https://www.tipsfound.com/excel/04isblank

 

関数の使い方自体はとても簡単で、式は下記のとおりです。

=ISBLANK([空判定をしたいセル])

なお、こちらの関数は指定したセルが空だったら TRUE を返し、何か値が入っていたら FALSE を返します。

この関数は IF 関数と一緒に用いることが多いと思います。
例えば、「セルが空だった時」と「空でなかった時」に処理を分けたいときに使えます。

=IF(ISBLANK([空判定をしたいセル]),[セルが空の場合の処理],[セルが空でない場合の処理])

サンプルコードは上記のとおりです。
この書き方を使えば、お店のセールなどでよくあるような「5,000円以上お買い上げで、10% オフ」という処理も簡単に書けます。
…まあ、Excel で実際に行う処理かどうかはわかりませんが…。

 

以上、Excel でセルが空かどうかを判定する方法でした。
私的には、頻繁には使わないけど思い出した時に使う関数だと思っているので、覚えておくと便利だと思います。

  • この記事いいね! (0)
村上 著者:村上

【Android】「Could not find com.android.tools.build:aapt2:3.4.2-5326820.」エラーの対処法

1年ほど前に開発したアプリを起動した際に遭遇したエラーについてです。
エラーメッセージは「Could not find com.android.tools.build:aapt2:3.4.2-5326820.」というもので、これだけでは意味が分かりません…。
なので、そのまま Google 検索にかけたところ、下記の記事がヒットしました。
若干エラーメッセージが異なりましたが、こちらの対処法で解消できました。

参考にしたサイトはこちら。

[Android]「Could Not Find com.android.tools.buildaapt2:3.2.0-4818971」という謎のエラーが出てビルドできない場合の対処法
https://minpro.net/could-not-find-com-android-tools-buildaapt2

 

こちらの記事によると、Android Studio のバージョンを挙げた時に発生するエラーのようです。
確かに、開発した当時とは Android Studio のバージョンは異なっているはずです。

で、解決方法ですが、build.gradle の中に google() を追加すればOKです。
追加箇所は下記のとおりです。

...
allprojects {
    repositories {
        google()  // こちらを追加
        jcenter()
    }
}
...

あとは、build.gradle を更新したので、Sync Now を実行し、通常通りビルド・実行をします。
私の環境では上記の追加のみで解決できました!

なお、こちらのエラーの原因ですが、参考サイトによると「Android Studio が 3.2 にバージョンアップされたとき、「AAPT2」というツールの提供元が変更されたことが原因」とのことでした。

 

以上、Android Studio にて「Could not find com.android.tools.build:aapt2:3.4.2-5326820.」エラーが発生した時の対処法でした。
参考になれば幸いです。

  • この記事いいね! (0)
著者:ym

7payの乗っ取りからID連携での対策

Yahoo! ID 連携の方法で、なにか情報がでた様なので引用します。

▼脆弱性のある実装方法
フロントエンドのJavaScriptやiOS,Androidのネイティブアプリで ユーザー識別子(sub)を取得しサーバーサイドへ送信するような実装をしている場合、 ユーザー識別子を送信しログインできてしまうため、不正にログインされる可能性があります。
そのため、上記のような実装は推奨しておりません。

▼推奨する実装方法
フロントエンドのJavaScriptやiOS,Androidのネイティブアプリではユーザー識別子を直接取得するのではなく、 サーバーサイド・アプリケーションで利用されるフロー(Authorization Codeフロー)を用いて認可コードを連携し サーバーサイドでユーザー識別子などの属性情報を取得してください。

https://developer.yahoo.co.jp/changelog/2019-07-18-yconnect.html

7pay を使用していなかったのですが、ログインする際の認証に使用する場合のところだと思います。

最近SNSを使用した認証が増えているので、注意してた実装が必要そうです。

  • この記事いいね! (0)
takahashi 著者:takahashi

突然MyDNS+Let’s Encryptでの証明書取得が不能に。原因はIPv6経由のアクセス。

たまたま自宅のサーバーのSSL証明を確認したら、Let’sEncryptで取得しているSSL証明書の有効期限が1か月を切っていました。

1か月に1回強制更新するように設定してあったのでおかしいなぁと思いつつ調べたところ、どういうわけか自宅サーバーからDNSサーバーへの接続がうまく行かなくなっていました。

自宅のサーバーではLet’s Encryptからワイルドカード証明書を取得しており、その際ドメインを管理しているDDNSのMyDNSと連動させることで自動で取得できるようにしています。
(詳細はこちらの記事をご覧ください。)

サーバーが接続しているインターネット回線はIPv6に対応しているため、SSL証明書を取得する際の接続先としてスクリプトで指定している”www.mydns.jp”への接続もIPv6で接続されるのですが、何故かMyDNSのIPv6アドレスに通信が到達できない状態になっていたのが原因でした。

他にもMyDNSに限らずサーバーからあらゆるドメインへのIPv6アドレス経由での接続ができなくなっているようだったので、どうやら自宅側のIPv6ネットワークがおかしくなってしまっているようでした。

とりあえず、接続先の指定をipv4.mydns.jpに変更してIPv4に固定したところ、問題なく通信できるようになったので、当分はこれでしのげそうです。

何故突然IPv6での接続ができなくなってしまったのかはまだ分かっていないのですが、まだまだ不安定なところがあるのかもしれませんね…

  • この記事いいね! (0)
村上 著者:村上

【Android】「Failed to validate the certificate chain, error: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.」エラーの対処法

先日報告があったため修正した、Android アプリの不具合です。
WebView のページを開いたところ、何も表示されず真っ白なページになってしまいました。

で、Android Studio で表示されたエラーメッセージは、タイトルにもある通り「Failed to validate the certificate chain, error: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.」というもので、「証明書チェーンの検証に失敗しました」とのこと。

このエラーは証明書の設定が間違っていることが考えられるので、一度証明書の設定を確認してください。

 

ですが、テスト用の証明書だったりするなど、直すのが難しいことがあるかと思います。
そんな時には、強制的にエラーをスキップする方法があります。

参考にしたサイトはこちらから。

Y.A.M の 雑記帳: Android WebView で https のサイトにアクセスして白画面になるのを避ける方法
http://y-anz-m.blogspot.com/2012/08/androidwebview-https.html

ssl – Android error in webview.loadUrl() – Trust anchor for certification path not found – Stack Overflow
https://stackoverflow.com/questions/33825696/android-error-in-webview-loadurl-trust-anchor-for-certification-path-not-fou

ただし、セキュリティ上は問題があるので、なるべく使わないほうがいいです。
あくまでも、緊急時の対処法ということにしておいてください。

対応方法ですが、WebViewClient を継承しているクラスがあると思うので、そこに下記のコードを記述します。

@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError er) {
    handler.proceed(); 
}

上記を指定すると、SSL でエラーが発生しても無視をしてくれますので、問題のあるWebページでも問題なく表示されます。

 

以上、Android の WebView で SSL 証明書にエラーがある Web ページを表示する方法でした。
ただし、再度繰り返しますが、あくまでも応急処置ですので、リリースするアプリには導入しないことをお勧めします。

  • この記事いいね! (0)
著者:ym

JMeter でのリモート実行できずに

Apache JMeter はサーバ1台で実行可能ですが、大きな負荷をかける場合は複数サーバに分散する仕組みが用意されています。

しかしこれがうまく動作しないのです。

create-rmi-keystore.sh

jmeter クライアント側で Java の keytool を使用して rmi のキー rmi_keystore.jks を作成。
これをリモート側 (jmeter-server) へコピーして準備します。もちろん rmi という名称部分は同じ様に指示通りに。
jmeter.properties などの .properties ファイル類の server.rmi.ssl.keystore を調整。コメントアウト化されているので、有効化してみたり。戻して見たり。

jmeter-server を起動させ 1099 ポートで待機させます。 クライアントは同じセグメント。

tcpdump しながら 1099 ポートへの通信を確認しているのですが、一行にタイムアウトで接続できず。

リモート実行する形での情報が少ないので非常に困り物です。

  • この記事いいね! (0)
著者:杉浦

【Vue】jQueryとVueを共存させる

 デザインはjQueryで作られる、実装はVue.jsで行う。なんやかんやあってこの方式でwebページを作る必要が出てくることがあります。一貫していた方が作りやすいはずなのですが、なんやかんやあってこうなります。
 デザインの実装の際、jQueryとVue.jsを読み込ませるとデザイン時に動いていたイベントが消える時があります。これはVueがテンプレートエンジンも兼ねていることが原因で起きがちです。例えば次の様なシナリオで起きます。

// デザイン時
HTML読み込み完了
↓
jQueryによるイベント付与実行
↓
全てのHTMLに付与されるべきイベントが付与されている

// 実装時
HTML読み込み中、Vue構築中
↓
HTML読み込み完了
↓
jQueryによるイベント付与実行
↓
Vue構築完了。Vue内で定義されたHTML構築を持ってきて描画

 特にVueでAPIの結果をHTMLの一領域に描画する仕組みを作った時はイベントの再定義の絡みで大体こうなります。こうなる時にはVueの中でVueが読み込み完了した場合に実行されるイベントでjQueryによるイベントを定義すると良いです。

export default {
  components: {
  },
  props: {
  },
  data() {
    return {
      
    };
  },
  mounted() {
    // jQueryのイベント付与処理
  },

 このように記述するとコンポーネントが読み込まれるたびにmounted関数が実行され、テンプレート内にjQueryのイベントが付与されます。
 Vue.jsとjQueryの同時実行はJavaScriptファイルが巨大になり初期読み込みが遅くなるため積極的に行うべきでないのですが、デザイナーからいただけるデザインにjQueryでアニメーションがついていることがしばしばあります。そういった際にこのやり方を知っておくと、Vue.jsの便利さから離れないままアニメーションを崩すことも再構築することもなくデザインを再現できます。

  • この記事いいね! (1)
asaba 著者:asaba

【cordova】cordovaのプラグインで天気予報を取得する方法

コルドバプラグインの中でも比較的メジャーなプラグインの一つであるcordova-plugin-geolocationですが、

このプラグイン使えば使うほど汎用性の高いプラグインだとじわじわ思い知らされます。

例えば、今いる自分の位置情報を取ってきたり、店舗や施設の位置情報を取って更に機能を展開したりと

短いコードですぐ取得できるので初心者にも易しい取説となっております。

これだけでも便利なのですが、オプションを変更するだけで天気予報も取得できることを知って自分の中で

更に評価が上がっております。

これが使えば天気予報を教えてくれたりその天気の情報によって振る舞いを変える機能を作ったりと

多岐に渡る活躍が期待できそうです。

サンプルコードですが、数十行で事足りるのでこれから実装したいと考えている方は参考にしてみてください。

</pre>
// Success callback for get geo coordinates

var onWeatherSuccess = function (position) {

Latitude = position.coords.latitude;
Longitude = position.coords.longitude;

getWeather(Latitude, Longitude);
}

// Get weather by using coordinates

function getWeather(latitude, longitude) {

// Get a free key at http://openweathermap.org/. Replace the "Your_Key_Here" string with that key.
var OpenWeatherAppKey = "Your_Key_Here";

var queryString =
'http://api.openweathermap.org/data/2.5/weather?lat='
+ latitude + '&lon=' + longitude + '&appid=' + OpenWeatherAppKey + '&units=imperial';

$.getJSON(queryString, function (results) {

if (results.weather.length) {

$.getJSON(queryString, function (results) {

if (results.weather.length) {

$('#description').text(results.name);
$('#temp').text(results.main.temp);
$('#wind').text(results.wind.speed);
$('#humidity').text(results.main.humidity);
$('#visibility').text(results.weather[0].main);

var sunriseDate = new Date(results.sys.sunrise);
$('#sunrise').text(sunriseDate.toLocaleTimeString());

var sunsetDate = new Date(results.sys.sunrise);
$('#sunset').text(sunsetDate.toLocaleTimeString());
}

});
}
}).fail(function () {
console.log("error getting location");
});
}

// Error callback

function onWeatherError(error) {
console.log('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
}
<pre>
  • この記事いいね! (0)