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

著者:杉浦

PhpStormのダイアグラム機能によるクラス図自動生成

 コードを読む時、しばしばクラス間の関係が記述されたクラス図が欲しくなる時があります。あると大変助かるのですが、大体そういったドキュメントはありません。PhpStormにはダイアグラム機能がついており、これはクラス図を始めとしたいくつかの図を自動生成する機能です。
ダイアグラムの操作 – 公式ヘルプ | PhpStorm
例えば、Laravelのソースコードの一部であるHTTPフォルダ以下のクラス図は次の様になります。

 図の矢印の意味は、矢印元は矢印先を参照して作られています、というもので、互いの依存関係を表しています。青の濃い矢印は直接の継承、緑の破線矢印はインタフェースの実装、白の破線ひし形矢印はトレイトの包含です。ただファイルを見るだけでは結構な量があり全貌をつかむまで時間がかかりがちですが、これならばすぐわかります。次の図はクラス図にしたHTTPフォルダ以下のフォルダ構造の木です。気持ち程度しか関係性が読み取れません。

 クラス図の例はPHPでしたが次の様にデータベース、JavaScriptなどにも対応しており、レイアウトのテンプレートも様々です。

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

【CSS】iOSでiframe要素が縦に伸びてしまうときの対処法

本日遭遇した現象で、iPhone で見たときに、iframe 要素が縦にびよーんと伸びてしまい、スクロールできませんでした。
ちなみに、Android では問題ありませんでした。
…この端末に依存するタイプの CSS のずれが本当に苦手…。

 

さて、こちらの対処法については、下記の Qiita の記事を参考にさせていただきました。

スマホサイトなどでiframe要素をスクロールさせる方法 – Qiita
https://qiita.com/ta__ho/items/904290fa0c8c60b25af1

まず、HTML要素は下記のようになっているものとします。


<div id='content'>
    <iframe src='[表示したいURL]' />
</div>

で、この時、CSS は下記の指定をしていました。

#content {
    width: 100%;
    height: 100%;
}
#content iframe {
    width: 100%;
    height: 100%;
}

Android であれば、上記のコードで問題ないのですが、iOS だと iframe 内の縦長のページが下に伸びてはみ出してしまい、スクロールすらできない状態でした。
そのため、#content に下記を追加します。

#content {
    width: 100%;
    height: 100%;
    /* 下記を追加 */
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

iframe には追加するプロパティはありません。
ここ重要なのは、overflow プロパティです。
overflow の初期値は visible で、要素に収まらない分ははみ出して表示するので、当然といえば当然ですね。
逆に、変更前のコードで動いてしまう Android が凄い…。
なお、横に伸びてしまう場合は、overflow-x プロパティを使用してください。

-webkit-overflow-scrolling プロパティでは慣性スクロールを有効にしています。
これを追加することで、滑らかなスクロールが実現できます。
これがないと、スクロール途中で突っかかって、スムーズにスクロールできず、かなりストレスになる場合があるので、iOS で利用される場合には、追加することをおすすめします。

 

以上、iOS で iframa 要素が縦に伸びてしまい、スクロールできない時の対処法でした。
どなたかの参考になれば幸いです。

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

Pythonのグローバル変数の命名における慣習

 Pythonはファイル全体をスコープとした記述が出来、例えば次の三行だけのファイルを動かせます。

print('---')
print('Hello, World!')
print('---')

 インタプリタらしく一行一行コマンドを読み込み、実行していく感じです。この一行一行がくせもので必ずファイル全体をスコープとしたグローバル環境にコードを記述する必要があります。例えば関数を定義して呼び出す際、最後はグローバルから呼び出すことになります。

def hello_world():
    return 'Hello, World!'


hello_world()

 この仕様によるグローバル汚染を防ぐためにPythonにはいくつか慣習があります。例えば、実行ファイル以外のコードが不意に走ることを防ぐためのif文があります。

def hello_world():
    return 'Hello, World!'


if __name__ == '__main__':# このファイルがメインの実行ファイルならばtrue
    hello_world()

 同じ様にグローバル変数には命名の慣習があり、ローカル内で誤ってグローバル変数を参照することを避けます。内容はいたってシンプル、先頭の_です。

def hello_world():
    return 'Hello, World!'


_msg = hello_world()
if __name__ == '__main__':# このファイルがメインの実行ファイルならばtrue
    print(_msg)

 この様にすることで複数ファイルを連携させた際に参照したい変数、参照したくない変数を操りやすくします。この慣習は根付いており、Python実行ファイル上において_hogeな変数とfugaな変数は同等に扱われるにもかかわらず、IDE等のPython対応のエディタにおいて_hogeな変数はグローバル変数用の扱い、fugaな変数はローカル変数用の扱いと区別されます。

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

【React】HTMLタグを有効にする「dangerouslySetInnerHTML」プロパティ

アプリの要件上、色々試しましたがこれが一番手っ取り早そうだったので導入しました。
React で a タグなどの HTML タグを有効にする方法です。
プロパティ名は「dangerouslySetInnerHTML」です。
ただし、プロパティ名からも察せられるように、XXS(クロスサイトスクリプティング)の危険性などから、使わないで済むなら使わないほうが良いとのこと。
また、プロパティ名は故意に怖がらせるような名付けをしているそうです。
注意して使う必要があることが分かりやすくていいですね。
ですが、ちゃんと中身のチェックをすればとても便利なプロパティです。

 

導入には、下記のページを参考にしました。

React の dangerouslySetInnerHTML を使用する際に最低限気にするべきこと – Qiita

javascript + Reactでhtmlタグの削除と許可とXSS対策 – joppot

2つ目の記事では、XXS 対策について詳しく書かれているので、参考になるかと思います。

さて、実装方法ですが、サンプルはこちら。

import React, { Component } from 'react';

class SamplePage extends Component {
  render() {
    const html = '<a href="[URL]">ページを開く</a>'
    return 

<div className='main' dangerouslySetInnerHTML={{__html : html}} />;
  }
}

変数 html に、有効にしたい HTML タグが含まれた文字列を定義し、それを dangerouslySetInnerHTML で指定した親要素の子要素として追加しています。
基本的な作業としてはこれだけ。
ただし、利用者が入力した情報など、どんな値が入ってくるかわからない場合は、きちんと内容のチェックを行いましょう。
script タグについては XSS の対処はできているとのことですが、a タグや iframe タグを利用する場合については、値は要チェックです。

 

以上、React で HTML タグを有効にする方法でした。
便利ですが、使用の際には十分ご注意ください。

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

【JavaScript】scrollTopが効かない時の対処法

先日遭遇したJavaScriptでの現象について。
タイトルにある通り、scrollTop プロパティに値を指定しても、その位置にスクロールしない現象が発生しました。
何故か scrollTop から返ってくる値が常に 0 になっており、それが原因のようです。

 

で、こちらの問題の解決にあたって、下記の記事が参考になりました。

document.body.scrollTopが常に0を返す謎を調べてみた – Qiita
https://qiita.com/tkengo/items/ee758c75ba874757b7fd

この記事によると、原因は scrollTop プロパティでスクロール位置を取得したい要素に下記の CSS を指定するとのことでした。

#sample {
    overflow-y: auto;
    width : 300px;
    height: 200px;
}

widthheight の値は任意です。
現状にあった値に適宜変更してください。

上記を指定することで、id='sample' の要素がスクロール可能な範囲となり、無事 scrollTop の値を取得することができるようになりました。

なお、HTML と JavaScript のサンプルコードは下記のとおりです。
JavaScript はボタン押下時など、任意のタイミングで実行してください。

<body>
    <div id='sample'>
        <!-- 要素の中身を記入 -->
    </div>
</body>
var element = document.getElementById('sample');
var scroll-top = element.scrollTop;

 

以上、JavaScript の scrollTop が効かない時の対処法でした。
JavaScript というよりも、CSS の修正でしたが、ご参考になれば幸いです。

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

【PHP】PHPDocからドキュメントページを作成するphpDocumenterの紹介

phpDocumentor
phpDocumentor/phpDocumentor2: Documentation Generator for PHP
 phpDocumentorはPHPDocを読み取り、PHPDocに従ってドキュメントを表すHTMLページを作成してくれます。インストールは次の画像やphpDocumentorの右側参照、要はvendor/bin以下にphpDocumentorの実行ファイルが置ければ何でもよいです。

 実行方法は次の画像の通りPHPを介して実行。コマンドは

php [phpDocumenter実行ファイル] -d [対象ファイル、フォルダのパス] -t [出力先のパス]

です。

 こうして出来上がったページが次の画像です。この様にnamespaceに従った階層でPHPDocに従ってメソッド、プロパティとその説明などが記述されます。
 
 自動生成で相当リッチなページが作られます。注意点としてリッチすぎてPHPDocを厳格に扱っていない場合、空欄による穴あきだらけになる点があります。

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

【React】「Uncaught TypeError: Cannot read property ‘prepareStyles’ of undefined」エラーの対処法

以前開発したアプリを修正中に遭遇したエラーです。
Uncaught TypeError: Cannot read property ‘prepareStyles’ of undefined」というエラーで、翻訳したところ、「捕捉されないTypeError:未定義のプロパティ ‘prepareStyles’を読み取ることができません」とのこと。
何か必要な定義を削除したようです。
が、かなり変更してしまったので、どこかを特定するのはやや面倒…。

…と思いきや。
対処法について書かれた記事が Qiita にありました!

記事はこちらから。

Reactでコンポーネントを作ってみる。 – Qiita
https://qiita.com/sho7/items/6bd2aec44b95cb3a7fed

どうやら、Material-UI を利用する時に必要な定義「MuiThemeProvider」が抜けていたことが原因だったようです。
サンプルコードは下記のとおりです。

import React,  {Component}  from 'react';
// 追加: MuiThemeProvider をインポート
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'

export default class TestPage extends Component {
  render() {
    return (
      <MuiThemeProvider>
        /* ページの内容 */
      </MuiThemeProvider>
    )
  }
}

3行目のとおりに、MuiThemeProvider をインポートし、さらにページ全体をこの <MuiThemeProvider> タグでラップします。
あとは、再度ビルド・実行すれば、このエラーは解消できるはずです。

 

以上、React で発生したエラーの対処法でした。
しかし…以前書いた自分のコードは見返したくないですね…。拙すぎる…。
とりあえず、今は修正に追われています。

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

【android】Android7.0でのUri取得方法について

復活したエミュレータでビルドをしたのですが、今度はFileUriExposedExceptionというエラーで詰みました。リファレンス曰く、Android7.0以降は、フレームワークによりfile:// URI の公開を禁止する StrictMode API ポリシーが適用されます。なのでAndroid7.0を対象にfile://と名の付くurlをインテントすると、このFileUriExposedExceptionを引き起こすみたいですね。自分のエミュレータも23以降は動いたのにApi24からカメラを起動しようとして落ちたので、恐らくuriを変換してfile://を受け取ろうとしたときにこれに引っかかったのだと思われます。なのでアプリ間でファイルを共有するには、content://URI を送信して、この URI への一時的なアクセス パーミッションを付与する必要があります。変換の仕方ですが、Android7.0以前では外部ファイルからuriを取得するときはUri.fromFileを使っていましたね。バージョンによって処理を場合は分岐させたい場合は、if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {}で分けておきましょう。

API24以前

imageUri = Uri.fromFile(picFile);

API24以降

Uri uri = FileProvider.getUriForFile(
getActivity(),
BuildConfig.APPLICATION_ID + ".fileprovider",
picFile);

マニフェストにも以下のタグを追加していきます。

<provider
    android:name="com.android.tools.ir.server.InstantRunContentProvider"
    android:authorities="パッケージ名"
    android:multiprocess="true" />
※authoritiesは、マニフェストの先頭部分にあるpackage=""から参照します。

レイアウトファイルにもBuildConfig.APPLICATION_IDがパスを取得できるようにパスを書いておきましょう。

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path android:name="external_files" android:path="." />
</paths>

以上がcontent://ファイルを取得する方法です。これからアプリを一から作る分にはさほど苦労しないかもしれないですが、前からあるプログラム相手だと既存の仕様と睨めっこしなければいけないのでここで骨が折れます。

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

【PHP】is_iterable()===falseでもforeachできるオブジェクト

 foreachは繰り返し要素を参照する制御構造です。次図の様に配列の中身を繰り返して扱う時によく使われます。

PHP: foreach – Manual
 is_iterableは変数の内容が反復可能な値であることを確認する関数です。次図の様に与えられた変数の型が配列などの数え上げが可能な型であるか否かを返しています。

PHP: is_iterable – Manual
 is_iterableは反復可能な値であることを確認する関数であり、foreachは繰り返し要素を参照する構文です。であるならば、ある変数$hogeに関してis_iterable($hoge)===falseの時、foreach($hoge as $h)が出来ないように思えます。しかしPHPはちょっと違います。

 is_iterable($hoge)===falseでありながらもforeachが実行されてvar_dumpの出力が表示されています。この現象の理由の一つはオブジェクトの反復処理の定義にあります。公式のマニュアルには次の様にあります。

PHP 5 は、たとえば foreach 命令などによる反復処理を可能とするよう オブジェクトを定義する手段を提供します。 デフォルトで、 全ての アクセス権限がある プロパティは、反復処理に使用することができます。

PHP: オブジェクトの反復処理 – Manual

 これが原因でオブジェクトはis_iterable===falseであってもforeachできます。foreachで参照する要素はアクセス可能なプロパティ全てです。
 foreachできるにもかかわらずis_iterable===falseになる原因はis_iterableが実際にやっている内容が上の画像の端的な説明と異なっている点にあります。実際の挙動においてis_iterableは反復可能な値であるか否かでなく、擬似型iterableを満たすか否かを判定しています。

変数の内容が iterable 疑似型で許容されること、すなわち array、あるいは Traversable を実装したオブジェクトであることを確認する。
PHP: is_iterable – Manual

 まさしく、is iterable?、と訊いているわけですね。
 上記二つの原因によって、iterable型を満たさないオブジェクトは反復処理が可能であるがis_iterable===trueになりません。正直直感的でない仕様であり、少しでもマシにしようとRFCを提出した人もいます。
PHP: rfc:iterable-stdclass

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

【android】外部ストレージからディレクトリを取得する方法

今回は完全に自分用の記事になっております。内容は、カメラで撮影した写真のディレクトリを取得する方法についてです。撮影した画像は、大体は外部ストレージ(SDカードのような)に保管されます。他のアプリを消しても写真を残しておきたいという時は、外部ストレージから取り出してやりとりしてあげればいいのです。今回は、外部ストレージにアクセスしてパブリックなファイルに新しいファイルを作ってくれる方法を書き残しておきたいと思います。(くどいようですが今回は完全に自分用なのでご容赦ください)

通常androidのような端末は、通常撮影した画像はDCIMというファイルに保存されます。DCIMとは、android本体に内蔵されているファイルのことで、アプリのカメラで撮影した画像を除く画像は、全てこのファイルに収納されます。このDCIMに保存されていれば、SDカードさえあればどのデバイスでも画像を共有して使うことが出来ます。このDCIMから続くディレクトリを取得するにはgetExternalStoragePublicDirectoryという関数を使う方法があります。この関数を使えば、パブリックなディレクトリ(自分のandroid付属のカメラで撮影した画像がある場所)をピンポイントで取得してくれるのです。urlを取得して加工したい時とか便利そうですね。

<pre>File imageStorageDir = new File(
  Environment
  .getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),
  "VG"
);</pre>
<pre>picFile = new File(imageStorageDir + File.separator + "IMG_"
  + String.valueOf(System.currentTimeMillis()) + ".jpg");</pre>

System.out.printlnで出力したものがこちら


I/System.out: /storage/emulated/0/DCIM/VG/IMG_1551774023376.jpg

new fileの引数にDCIMに続くVGファイル、更に先のIMG、数値の入ったipgが連結されて出力されているのがわかると思います。

今ではもう古い技術ですが、覚えておくとディレクトリ取得のモデルというか応用で役に立つので損はないかと思っております。

  • この記事いいね! (0)