カテゴリーアーカイブ 言語

村上 著者:村上

【HTML】標準のHTMLから動画を再生するための<video>タグ

実は使ったことがなかったので、使い方を簡単にまとめ。
動画を再生する際に使用する、<video>タグです。
Flashなどのプラグイン導入が不要で、手軽に動画を扱うことができます。

 

実装はとても簡単で、下記のように指定するだけ。

<video src="[動画ファイルのパス]"></video>

ほどんど <img>タグの感覚で使えます。

また、下記のような指定をすることで、その再生できるファイルの候補をいくつか指定することもできます。

<video>
  <source src="[動画ファイル1.mp4]">
  <source src="[動画ファイル2.ogv]">
</video>

上記のように <source>タグを使い、複数の動画ファイルを指定できます。
ブラウザは、上から順に再生可能な動画データを再生するので、仮に mp4が再生できなくても、その次の orv を再生してくれます。

また、この<video>タグにはいくつかの属性があります。
まず autoplay属性で、こちらはその名のとおり、自動で動画を再生してくれます。
次に、preload属性で、ウェブページを読み込んだ時点で動画を裏側で読み込みをしてくれます。
こちらはデフォルト値は auto で、一般的なブラウザでは、特に明記しなくてもあらかじめ読み込みをしてくれます。
もし、事前読み込みを禁止したい場合は preload="none" を指定します。
controls属性を指定すると、再生・一時停止・再生位置の移動・ボリューム などのメニューを表示するようにしてくれます。
最後に poster属性で、これは指定した動画ファイルが再生できなかった時に表示する画像を指定できます。
これは、<img>タグのalt属性のようなイメージですね。

 

以上、HTMLで動画の再生をする時に使える <video>タグのご紹介でした。
Youtubeの埋め込みの印象が強く、動画の再生=ifremeというイメージがあったのですが、こんな簡単に実装できたのですね。

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

trait中の関数を差分プログラミングをする

 traitはクラス中に現れる共通のプロパティ、メソッドをまとめて記述するための仕組みです。コード中におけるその扱いは継承に似ています。継承を行った場合、スコープ定義演算子をもちいることによってコードをコピペせずにちょっとだけ処理を付け足すことが出来ます。

class ChildHoge extends ParentHoge
{
  public function __construct()
  {
    //親のコードの処理前に付け足す処理の部分
    parent::__construct();
    //親のコードの処理後に付け足す処理の部分
  }
}

 このように便利なスコープ定義演算子ですが、traitを指すことはできません。traitでこれに似たことをしたい時、名前の変換を行うことによって実現ができます。元のコードを別名として扱い、traitを読み込んだクラスで元々の名前のメソッドを実装することによってクラス外のふるまいを変えることなくちょっと付け足しただけの差分プログラミングができます。

class ChildHoge
{
  use FugaTrait {__construct as traitConstruct;}
  
  public function __construct()
  {
    //トレイトのコードの処理前に付け足す処理の部分
    $this->traitConstruct();
    //トレイトのコードの処理後に付け足す処理の部分
  }
}
  • この記事いいね! (0)
takahashi 著者:takahashi

bashシェルスクリプトで引数の取得と空文字を判定する方法

以前村上さんが 【備忘録】MacのFinderで隠しファイル・フォルダを表示する方法 という記事を投稿されてましたが、自分の場合はこちらの内容を参考に簡単に切り替えれるようにシェルスクリプトでon offをできるようにしています。

とりあえず簡単に作ったのでめっちゃ簡素です(;´∀`)

#!/bin/bash

echo 'please type "true" or "false": '
read com

if [ $com = "false" ]; then 
  defaults write com.apple.finder AppleShowAllFiles FALSE
  killall Finder
  echo "隠しファイルが非表示になりました。"
fi

if [ $com = "true" ]; then
  defaults write com.apple.finder AppleShowAllFiles TRUE
  killall Finder
  echo "隠しファイルが表示されました。"
fi

exit 0

シェルスクリプトを作るとき、とりあえず簡単に作っておこうと思って

コマンド実行->隠しファイルの表示、非表示(true or false)を入力

という作りにしたのですが、これだけの操作でわざわざ2段階にする必要ないよなぁ、と思い、

コマンド true
コマンド false

でできるようにしようと思いました。

bashのシェルスクリプトで引数を認識させるのはとても簡単で、

コマンド 引数1 引数2 ... 引数n

とした場合に、引数の値をとる場合は

引数1: $1
引数2: $2

引数n: $n

という変数でそれぞれ取ることができます。
(引数10個目以降の引数の取得については${10}といった書き方をする必要があるようです。)

ただ、折角コマンド内で入力を読み込む処理も書いてあったので、今回は引数が何も入力されなかった時に、従来のtrue or falseを質問するプロンプトを表示するように変えてみました。

ここで”何も入力されなかった”、つまり空文字を判定する必要が出てきます。

PHPなどでは

//もし空だった場合
if($hoge == "")
{ 
    /*処理*/ 
}

みたいに書きますが、bashの場合は

#hogeが空だった場合は処理を実行
if [ -z "$hoge" ]; then
  #処理
fi

と書きます。
ちなみに、”空でなかった場合”に処理をさせたい場合は

#hogeが空でなかった場合は処理を実行
if [ -n "$hoge" ]; then
  #処理
fi

と書けばよいそうです。

これを踏まえてこんな感じに変更してみました。

#!/bin/bash

com=$1 #引数取得

if [ -z "$com" ]; then #もし引数に値が入ってなければ
  echo 'please type "true" or "false": ' 
  read com #再入力を要求
fi

if [ $com = "false" ]; then #"false"が指定されたら
  defaults write com.apple.finder AppleShowAllFiles FALSE #finderで隠しファイルを隠すコマンドを実行
  killall Finder
  echo "隠しファイルが非表示になりました。"
fi

if [ $com = "true" ]; then #"true"が指定されたら
  defaults write com.apple.finder AppleShowAllFiles TRUE #finderで隠しファイルを表示するコマンドを実行
  killall Finder
  echo "隠しファイルが表示されました。"
fi

exit 0

この内容をテキストファイルとしてユーザーがアクセスできる場所(例えば/usr/local/bin/ とか /opt/ とか)に保存し、”chmod +x”などを行って実行権限を与えておきます。
これでお手軽隠しファイル表示/非表示コマンドの完成です。

bashなどのシェルが使える環境では、こういったシェルスクリプト(バッチファイル)を作っておくことで、複数のコマンドを打たないといけないような操作を1コマンドで済ませたりすることができるようになります。

便利なので是非活用してみてください。

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

【Cordova】端末内のファイルを開く「cordova-plugin-file-opener2」をiOSでも使う

先日投稿した、「cordova-plugin-file-opener2」を使って端末内のファイルを開く方法の、iOSバージョンです。
思ったよりも簡単に実装できました。

プラグインはこちらからご確認ください。

GitHub – pwlin/cordova-plugin-file-opener2: A File Opener Plugin for Cordova
https://github.com/pwlin/cordova-plugin-file-opener2

ちなみに先日の投稿についてはこちらから。

【Cordova】端末内のファイルを開くプラグイン「cordova-plugin-file-opener2」
https://cpoint-lab.co.jp/article/201812/【cordova】端末内のファイルを開くプラグイン「cordova-plugin-file-op/

 

さて、実装方法ですが、コード自体は下記のとおりです。

let filePath = [開きたいファイルのパス];
if (window.device.platform === 'Android') {
  filePath = filePath.replace(/^file:\/\//, '');
}
window.cordova.plugins.fileOpener2.open(
  filePath,
  'image/png',
  {
    error: function() {
      // エラー時の処理
    },
    success: function() {
      // 成功時の処理
    },
  }
);

異なる点は開きたいファイルを指定しているパス値のみで、それ以外は先日に投稿したコードとほぼ同じです。

Android と iOS では開くファイルのパス指定方法が異なるので、まずは端末が Android なのか iOS なのかを判断します。
上記のコードでは、3行目にあたります。
使用しているプラグインは「cordova-plugin-device」です。

GitHub – apache/cordova-plugin-device: Apache Cordova Plugin device
https://github.com/apache/cordova-plugin-device

device.platform で、Android や iOS などの、プラットフォームを示す文字列が取得できるので、それを使って判断しています。
で、Androdだったら、文頭についている file:// をとり、iOS だったらそのままです。

あとは、取得・整形したファイルパスとファイルのMIMEタイプを fileOpener2 のプラグインで指定して、ファイルを開く処理を実行します。
そうすれば、指定したファイルが展開されるはずです。

 

以上、iOSで端末に保存されたファイルを開く方法でした。
Androidは、サンプルコードから文頭の file:// が不要ということが分かったのですが、iOSの指定方法が見つけられず…。
で、試しに取得したファイルパスを加工せず、そのまま指定したところ、問題なく実行されたという次第です。
行き当たりばったりな気もしますが、動いたので問題なし!ということにします。

ということで、Android・iOSの両端末でのファイル展開機能の実装については、これで対応が完了です。

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

foreachとPHPDocとIDE

 IDEの補完機能は便利です。複雑なオブジェクトのプロパティ、メソッドを網羅し、入力をサポートしてくれます。
 
 これは変数の型を推論することと型の内容を把握することによって実現されています。ここでforeachを使った場合、次の様になる時があります。

 静止画のためわかりにくいですが、予測が出来なくなっています。これは推論が不能になったため起こっています。型推論の主な道筋はそれを導くために用いられた関数、演算子などによる型の連想です。ここで起こっていることはarrayの中に入っている値の型が推論できない、ということです。これを解決するためにPHPDocによる型の説明を用いることが出来ます。

/** @var Members $member */

 このPHPDocコメントを書くことによって$memberはMembers型であるとIDEに示すことができ、IDEは型による補完機能を動かしてくれました。

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

phpの三項演算子の一種エルビス演算子

PHP: 比較演算子 – Manual

PHP 5.3 以降では、三項演算子のまんなかの部分をなくすこともできるようになりました。 式 expr1 ?: expr3 の結果は、expr1 が TRUE と同等の場合は expr1、 それ以外の場合は expr3 となります。

 phpの三項演算子は真ん中の部分を省略して記述することが出来ます。この記述?:はエルビス・プレスリーの顔文字にならってエルビス演算子と通称されています。google画像検索などではエルビス・プレスリーの写真に?:を当てはめた画像が大量にヒットします。エルビス演算子による記述を用いたコードは次の様になります。

$c = $a ? $a : $b;
$c = $a ?: $b;

 {}もelseも必要にならないが条件分岐が欲しいときはよくあります。特定の条件――次の例では投稿された記事の編集権限の有無――によって早期returnを促すガード節はエルビス演算子を用いることによって簡単に記述できます。

auth()->user()->hasAccess($edit_post) ?: abort('403');

 null合体演算子??は$hoge ?? $fugaでisset($hoge) ? $hoge : $fugaという式を表していたのに対し、エルビス演算子は緩やかな比較を用いたTRUEであるか否かの式を表します。$hoge ?: $fugaならば $hoge == true ? $hoge : $fugaといった具合です。これにより次の画像の様な違いが現れます。

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

【Cordova】端末内のファイルを開くプラグイン「cordova-plugin-file-opener2」

前回、端末に画像や音声ファイルをAndroidなどの端末にダウンロードするプラグインを紹介したので、今回は端末内のファイルを開く方法について。
使用したプラグインは「cordova-plugin-file-opener2」です。

GitHubは下記からご確認ください。

GitHub – pwlin/cordova-plugin-file-opener2: A File Opener Plugin for Cordova
https://github.com/pwlin/cordova-plugin-file-opener2

 

プラグインの導入は、例のごとく下記のコマンドを実行します。

cordova plugin add cordova-plugin-file-opener2

使い方はとても簡単で、下記のように開きたい端末内のファイルのパスと、その MIMEタイプを指定するだけ。

cordova.plugins.fileOpener2.open(
    [開きたいファイルのパス], 
    [ファイルのMIMEタイプ], 
    {
        error : function(){
            // ファイル展開 失敗時に実行する処理
        }, 
        success : function(){
            // ファイル展開 成功時に実行する処理
        } 
    } 
);

ファイルのパスは、/storage/emulated/0/Pictures/[ファイル名].jpg のような感じで指定します。
こちらのパスの値については、私の環境では、ファイルダウンロードに成功した時に取得できる file:///storage/emulated/0/Pictures/[ファイル名].jpg から、file:// を取ったものを使っています。

ご覧の方の環境に合うかは分かりませんが、参考にコードを記載しておきます。

window.document.addEventListener('DOWNLOADER_downloadSuccess', function(event) {
  const data = event.data;
  const filePath = data[0].nativeURL.replace(/^file:\/\//, '');

  if (fileMIMEType !== null) {
    window.cordova.plugins.fileOpener2.open(
      filePath,
      'image/png',
      {
        error: function() {
          // ファイル展開失敗時の処理
        },
        success: function() {
          // ファイル展開成功時の処理
        },
      }
    );
  }
});

こちらはとりあえずAndroidで動作するようにしてあるだけなので、iOS には対応していません。これからやります。
なお、MIMEタイプについても、とりあえず png 形式のみ対応なので、もし扱うファイル種類が定義されていない場合は、拡張子で jpg、gif くらいは判断できるようにしたほうが良さそう。

ちなみに、動作確認中に、うっかり音楽ファイル(mp3)を imgae/png で開いてしまいましたが、エラーにはならず、ファイルが壊れているような表示になりました。
その後、きちんと audio/mp3 にしたら、開くアプリの選択肢が表示され、再生もできるようでしたので、音声ファイルも問題なさそうです。

 

以上、Android端末内のファイルをアプリで開く方法でした。
とりあえず、Androidに問題がなかったので、iOS でも使えるように修正していきたいと思います。

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

laravelのEloquentクラスのbootメソッド

 laravelはモデルの基盤をEloquentというクラスで定義しています。boot()はこのEloquentが呼び出されたときに走ることになる関数です。laravel5.6のソースコード(vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php)には次の様にあります。

    /**
     * The "booting" method of the model.
     * モデルの「初期起動」メソッド
     *
     * @return void
     */
    protected static function boot()
    {
        static::bootTraits();
    }

    /**
     * Boot all of the bootable traits on the model.
     * モデル上の起動可能なすべてのtraitを起動します
     *
     * @return void
     */
    protected static function bootTraits()
    {
        $class = static::class;

        $booted = [];

        foreach (class_uses_recursive($class) as $trait) {
            $method = 'boot'.class_basename($trait);

            if (method_exists($class, $method) && ! in_array($method, $booted)) {
                forward_static_call([$class, $method]);

                $booted[] = $method;
            }
        }
    }

 これにある様にbootはbootTraitsを呼びだしbootTraitsは頭にbootクラス名とあるtraitのメソッドを呼び出します。bootメソッドに追記する事、bootトレイトを作ることでモデル呼び出し時に様々なことが出来ます。特に便利な使い方はグローバルスコープです。グローバルスコープは次の様に記述する事でクエリビルダを呼び出す際に必ず記述したクエリがつくというものです。

    protected static function boot()
    {
        parent::boot();
        static::addGlobalScope('auth_post', function (Builder $builder) {
            $post_key = Users::findOrFail(auth()->id())->post_key;

            $builder->where('post.primary_key', $post_key);
        });
    }

 上記のコードでは今ログインしているuserに関連するpostでwhereをかけています。ログインしているユーザに関してのみのデータを扱う、という処理は頻繁に現れます。このようなほぼ必ずするべき記述をモデルクラス内の各メソッドで何度も記述することは無駄であり、bootメソッドの利用はこれを解決します。

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

【Cordova】端末にファイルをダウンロードするプラグイン「cordova-plugin-file-downloader」【解決済】

昨日投稿した、「cordova-plugin-file-downloader」について、問題なく動作させることができたので…というか、ダウンロードできていたことが分かったので、それのご報告です。

昨日の記事はこちらから。

【Cordova】端末にファイルを保存するプラグイン「cordova-plugin-file-downloader」【未動作】
https://cpoint-lab.co.jp/article/201811/【cordova】端末にファイルを保存するプラグイン「cordova-plugi/

 

ダウンロードしたファイルの確認方法ですが、私の端末(Android 7.0)では「ダウンロード」アプリから確認ができました。
まず、アプリ一覧から「ダウンロード」アプリを開き、サイドメニューから、端末のローカルストレージを選択します。
画面イメージは下記のとおりです。

ローカルストレージを選択すると、フォルダ一覧が表示されるので、ここからプラグインの初期設定時に folder で指定したフォルダ名を探します。
無事見つかれば、このフォルダ内にダウンロードしたファイルが保存されているはずです。

ちなみに、そのコードはこちら。

downloader.init({folder: "[端末の保存先ファイル名]"});

ということで、ただ単に私がダウンロードが完了したファイルを探せなかっただけでした!
大変失礼致しました…!

 

さてしょうもない結末だったので、ダウンロード後の処理を記述する方法についてご紹介したいと思います。
オプションに onSuccess とかの指定ができなかったので、てっきり出来ないかとも思いましたが、ちゃんとありました!
コードは下記のとおりです。

document.addEventListener('DOWNLOADER_downloadSuccess', function(event) {
  const data = event.data;
  console.log(data[0].name);
  console.log(data[0].fullPath);
  console.log(data[0].nativeURL);
});

document.addEventListener の第一引数で、DOWNLOADER_downloadSuccess を指定すると、ファイルのダウンロードに成功した時にこの関数が呼び出されます。
で、変数 event に、データが入っているので、上記のように指定すると、ファイル名や保存先のパスなどが取得できます。

第一引数は、他にも DOWNLOADER_downloadErrorDOWNLOADER_downloadProgress なんかもあるので、ご要望に合わせて使い分けてください。

 

以上、cordova-plugin-file-downloader を使ったダウンロード方法とダウンロードしたファイルの確認方法でした。

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

PHPのNull合体演算子

 PHPはユーザの投げてきた値、DBから取得した値といった、存在するかも怪しい値を扱うことが多いです。この問題への対策の定番は条件文とissetです。issetは変数がセットされていること、そして NULL でないことを検査する関数です。
PHP: isset – Manual
PHP: PHP 型の比較表 – Manual
条件文とissetを用いて真面目に素朴な書き方をするならば次の様になります。

if(isset($_GET['user'])){
    $user = $_GET['user'];
} else {
    $user = 'nobody';
}

 5行になりました。この処理と同じ処理を何度も記述する場合、ソースコードは巻物の様に長くなります。条件文がシンプル、行う処理もシンプル、であるならば三項演算子がきれいに記述をしてくれます。三項演算子を用いた例は次になります。

$user = isset($_GET['user']) ? $_GET['user'] : 'nobody';

 1行に収まりずいぶんましになりました。しかしながら、ある値が存在するならばその値を扱うという処理は定番であり、三項演算子を用いた場合、二重にある値――例ならば$_GET[‘user’]の繰り返し――が冗長です。Null合体演算子はこれを解決します。Null合体演算子による記述は次です。

$user = $_GET['user'] ?? 'nobody';

PHP: 比較演算子 – Manual
 もうこれ以上ないくらいシンプルな記述になりました。最初のif文と同じ働きをしますが行数は1行、横の長さも大して変わりません。長大な参照名がついてしまっていても変数を増やさず二行で書けます。

$user_point_total = User::findOrFail($_POST['primary_key'])->userPointTotal->point_total
   ?? UserPointTotal::$default_points;
  • この記事いいね! (0)