2016年12月30日金曜日

PHP / laravel入門2

あくまでも自分用のメモ

引き続きドットインストールのお世話になります。
今回もlaravelフレームワークのメモを残していきます。


メモ

php artisan tinker
tinkerの起動

>>> App\Post::all()->toArray();
配列の形で全てのインスタンスを出力する

>>> App\Post::where('id', '>', 1)->get()->toArray();
配列の形で特定のインスタンスを出力する

>>> App\Post::where('id', '>', 0)->orderBy('updated_at', 'desc')->get()->toArray();
orderBy('updated_at', 'desc')で並び替え
昇順はasc、降順はdesc

>>> App\Post::where('id', '>', 0)->orderBy('updated_at', 'desc')->take(1)->get()->toArray();
take(1)でレコード数を制限する。上から1個みたいです。

$post = App\Post::find(2);
>>> $obj = App\Post::find(2);
find(2)で該当のIDのレコード(オブジェクト)を返す。

>>> $post->title = 'title was changed';
プロパティの代入。

>>> $post->save();
変更の保存。

>>> App\Post::find(2)->update(['title'=>'title was changed again']);
update()でプロパティの->save()と同等の効果です。
ずいぶんすっきりしているORMで慣れればわかりやすいかもしれない。




ルーティング

サーブレット・Springフレームワークの言うところのリクエストマッピングですね!

app/Http/routes.php
laravel 5.2以前の場合

routes/web.php
laravel 5.3以降の場合

$ tree -L 2
PHP/laravel関係ないですが、
tree打ったら必要以上に出力された。。
パスの深さの指定は -L n

laravelのバージョン確認
php artisan --version
Laravel Framework version 5.3.28

Route::get('/', function () {
    return view('welcome');
});
/(ドキュメントルート)でアクセスされたら、
viewのwelcomeにアクセスする、という設定。
welcomeは/resources/views/welcome.blade.php

Route::get('/{num}', function ($num) {
        return 'get ' . $num;
});
ドキュメントルートに文字列を付与すると、
get 文字列
という文字列を返す。

Route::get('/', function () {
    return view('posts.index');
});
パスセパレータが.ドット
これで、resources/views/posts/index.blade.phpにアクセスできる

PHP/基本のメモ5

今回はメソッドを中心にメモを残します。


メモ

M_PI
円周率の定数

array_push($array, $var, $var2)
$array = [$var];
$array = [$var2];
と同じですが、array_pushは複数の要素を配列に格納できます。
どちらも配列の末尾に追加です。

sort($array)
配列をソートする

echoとprint
echo:関数。複数の引数を出力できる
print:言語構造。1つの引数しか出力できない

is_a(変数, クラス名を示す文字列)
変数がクラスのオブジェクトがを判定する

property_exists(変数, プロパティ名を示す文字列)
変数がプロパティを持つかを判定する

method_exists(変数, プロパティ名を示す文字列)
変数がメソッドを持つかを判定する

method_exists(変数, プロパティ名を示す文字列)
変数がメソッドを持つかを判定する

プロパティの定数はconst
定数名に$をつけないこと。

クラス定数へのアクセス
クラス名::定数名
$はつけない
クラスメンバへのアクセス(staticなプロパティ、メソッド)も同じ

PHP/基本のメモ4

マイナーなPHPのメモ


メモ

mt_rand(start_num, end_num)
rand()より精度が高い乱数をより早く返せるとのこと。
メルセンヌ・ツイスタを実装って公式にはあるけど、実装が正しくないバグがあったそうです。。。
PHP の mt_rand() は一貫して壊れている(consistently broken)らしい

...まぁ用途によっては気にしなくても大丈夫なのかな。
引数を含む2つの値の間の整数のいづれかを返します。
start_num > end_numの場合はfalseを返します。

$_SERVER
実行環境に関する情報を保存する予約変数
連想配列です。

$_SERVER["SCRIPT_NAME"]
現在のファイルのドキュメントルートからの相対パスを保持しています。
自リンクを作る際に使います。

$_SERVER["PHP_SELF"]
URLの、実行スクリプト以下の部分も含まれてしまう。
URLに実行したいJavaScriptを書いておくで、リンクにスクリプトを埋め込むことができてしまう
そのため、$_SERVER["SCRIPT_NAME"]を使いましょう。

__FILE__
マジック変数の一つ
実行した箇所のファイル名(includeされた箇所ならinludeファイル)のフルパス
※サーバ上でのフルパスですよ!

git commit -a
PHP関係ないですが、自分の認識が間違っていて、気づくのに時間がかかったので、メモ
新規ファイルは上記の-aしてもaddしてくれません。
しょうがないので、きっちり、git addしてからgit commitです。

PHP5.4からは配列の初期化は[]でもオッケー
array()で初期化するものだと思っていましたが、[] , [2,3,4]の形でも配列の初期化ができるとのこと
もう、Perlばりに書き方いろいろあるなぁ。

shuffle(配列)
配列をシャッフルする(システム?)関数
PHPのオブジェクトなしでよびだせる関数ってなんていうんでしょうね。とりあえずシステム関数と読んでみます。

array_slice(配列、オフセット、要素数)
配列のオフセット分ずらした添字の要素から要素数分の配列を返します。
オフセットが配列のサイズより大きい時は、空の配列を返します。

htmlspecialchars($s, ENT_QUOTES, 'UTF-8');
&, >, <, ", ' をHTMLエンコードする
今のWebアプリでは必須。お忘れ無く。
ENT_QUOTESはシングルクォート、ダブルクォートを共にエンコードするという設定
最後の'UTF-8'は見たまんま文字コードの指定です。

<?= 'Hello, World!' ?>
<?php echo 'Hello, World"' ?>と同じ

ini_set('display_errors', 1);
設定を変更します。
display_errorsは、画面にエラー出力を表示させるかどうかです。
デフォルトは1です。

2016年12月29日木曜日

Macのhostsファイルどこだっけ?

/private/etc/hostsでした

Excel VBA入門

引き続きドットインストールのお世話になります。
Excel VBAを書く機会が近々ありそうなので、ドットインストールで復習です。
手元に製品版のエクセルがない(Win版があるけどWinPCがめっさ重い)ため、
動作確認はできてません。復讐のため可とします。


メモ

リファレンス
マイクロソフトのものはオススメしない
Office 田中がオススメ
テストセンターのOdyseyが運営しているmoug
あとはググれば大抵の問題は解決できます。書籍もたくさん出ているので適当に。

コメント
’シングルクォートです。

エディター・IDE
VBE
開発タブ(リボン)を表示させないと出てこないアレ

用語
ワークブック
ワークシート
セル
オブジェクト:操作の対象
プロパティ:属性
メソッド:振る舞い

よく使うウィンドウ
プロジェクトウィンドウ
プロパティウィンドウ

プロシージャのテンプレート
Sub WriteHello()
  MsgBox ("hello")
End Sub
Sub:プロシージャの始まりを宣言
MsgBox:ポップアップでメッセージを表示するメソッド
End Sub:プロシージャの終わり
改行:行の終わりを示す(;セミコロンじゃない)
 _(スペースとアンダーバー):行の途中で改行
最初の一文字:キーワードやメソッド、プロパティはだいたい最初の一文字は大文字(確かVBEが補正してくれたはず)

セルの操作・値の代入
Worksheets("Sheet1").Range("A1").Value = "Hey"
Range("A2").Value = "Hey"
Cells(3,1).Value = "Hey"
Cells(3.1).Offset(1,0).Value = "Hey"
上記の例では、A1 - A4にそれぞれHeyと入力される。
シートの指定がなければ、アクティブなシートに対して実行される。
また、最後のValueについては、セルの標準プロパティでもあるので、省略することが可能です。
実行速度も、省略してもしなくても差はないそうです。参照:Office 田中
Rangeはセル番地を文字列として指定するのに対し、CellsはCells(行番号、列番号)と数値で指定します。
僕は”行列”という言葉で順番を覚えています。Offsetは指定した行数と列数分、セルの指定をずらします。
数が増えるほど、右下に移ります。

複数のセルの操作
Range("A1","C3").Value = "Hey"
Range("A1:C3").Value = "Hey"
どちらも、A1からC3までのセル範囲の全てのセルに、Heyと入力します。
下の書き方は変数入れづらかったような気がする。
Range("A:A").Value = "Hey"
Range("1:1").Value = "Hey"
上はA列全てのセルに、下は1行目全てのセルに、Heyと入力します。

Cells.Clear
全セルの内容と書式の消去です。
内容のみ:ClearContents
書式のみ:ClearFormats
コメント:ClearComments
アウトライン:ClearOutline 

With
対象をEnd Withまで操作対象を省略できる
Range("A1").Value = "Hey"
Range("A1").Font.Bold = True
Range("A1").Font.Size = 16
Range("A1").Interior.Color = vbRed
            ↓
With Range("A1")
  .Value = "Hey"
  .Font.Bold = True
  .Font.Size = 16
  .Interior.Color = vbRed
もしフォントの操作の2行だけなら、With Range("A1").Fontって書いてもOKです。
あと、Endブロックを入れ子にしてもオッケーです。

Range("B2").Delete shift:=xlShiftLeft
セルの削除。
shift:はオプション
セルB2を削除して左に詰める

Worksheets.Add after:=Worksheets("Sheet1"), Count:=2
ワークシートの追加
複数のオプションが設定可能で、2個目以降のオプションはカンマで区切る
例の操作は、Sheet1のあとに2枚ワークシートを追加する。

マクロの記憶
この機能のおかげで、全部を覚える必要はないため、助かる。
ただし、無駄な記録を削るのに少し調べる必要があったりする。

Dim 変数 As データ型
変数の宣言。
VBAでは変数宣言は必須ではないが、見つけづらい文法エラーになるので、常に変数宣言したほうがいい。
モジュールの頭に(つまり、Subの宣言より上に)Option Explicitと書くと、変数の型を明示しろっていうオプションが付く。
これが付いていると変数を宣言せずに使うとエラーが発生する。

変数宣言しない怖さはOffice田中をご参照ください。

Debug.Print 変数
イミディエイトウィンドウに変数の値を表示する

数値演算
あまり:mod
べき乗:^

変数の型
Integer
Double
Data:"yyyy/mm/dd"
Variant
Boolean:True/False
Range:初期化時はSetをつける(Set ran = Range("A1")

Excelの日付の扱い
シリアル値(連続した値)として内部的に保持している。
1900/1/1 0:00が内部値「1」で、1日ずつ「1」増えていきます。
これはVBAでも同じらしく 日付に「+1」すれば1日後の値となります。

配列
Excel VBAで配列を使うには、下記2つの方法があります。
Dim fruits(3) As String
fruits(0) = "Apple"
fruits(1) = "Banana"
fruits(2) = "Orange"
Dim fruits As Variant
fruits = Array("Apple", "Banana", "Orange")
他の言語同様、添字はゼロ始まり。

条件分岐If
If Range("a1").Value = "Apple" Then
  MsgBox ("Apple")
End if

Select
他言語のswitch相当
Select Case fruit
Case "apple"
  xxx
Case "banana"
  xxx
Case Else
  xxx
End select

Loop処理
Dim i As Integer
i = 1

Do While i < 10
  Cells(i, 1).Value = i
  i = i + 1
Loop
Dim i As Integer
For i = 1 To 9 Step 1
  Cells(i, 1).Value = i
Next i
最近VBA書いてなかったから、懐かしい。。。

Foreach
Dim fruits As Variant
fruits = Array("apple", "banana", "orange")

For Each fruit In fruits
  MsgBox (fruit)
Next

プロシージャの種類
Subプロシージャ:戻り値を持たない Functionプロシージャ:値を戻す

引数の受け取り
Sub Greet(ByVal name As String)
値渡しだとByVal
参照渡しだとByRef

引数の受け取り
Sub Greet(ByVal name As String)
値渡しだとByVal
参照渡しだとByRef

判定式
等しい:=
等しくない:<>

PHP / 配列へのアクセス / [] でも{}でもいいんかい

$array[0] でも $array{0]でもどっちもOKなPHP
どちらにしてもゼロから添字は始まります。

PHP / : コロンでも{} 括弧でもいいんかい

まだまだ驚き溢れるPHPの世界。
PHPの制御構文は、{}だけでなく:コロンでブロックを表現できるとのこと。 Pythonみたいね。

メリット

少しだけhtmlに埋め込んだ時に見た目が改善されます。うん、少しだけ。

if (xxx) { => if (xxx): 
 } else {  => else:
 }         => endif;  
if、 while、for、 foreach、switch が対応しているとのこと。
参照:公式ドキュメント

PHP / elseif /else if

PHPだとelseifともelse ifとも書けるんかいな。。。
結果はどちらでも書いても同じですが、内部的な処理が違うとのこと

複数の elseif を同じ if 文の中で使用することができます。
TRUE と評価された最初の elseif 式を実行します。PHP では、(単語二つで)'else if'と書くこともできます。
動作は(一単語の) 'elseif'と同じです。文法的な意味はやや異なっています
(あなたが C 言語に詳しいとすると、C 言語のそれと同じ動作です)。 しかし、最終的な両者の動作は全く同じです。
抜粋:公式ドキュメント

else ifだと、最初のif条件式がfalseの場合にさらにifブロックがある(入れ子構造)、ということみたいですね。

一方、一単語のelseifだと、最初のif条件式がfalseの場合に、同じ階層に条件判定する式がある、ということみたいです。
まぁどっちでも書けて、結果は変わらないということだけ覚えときゃいいか。

PHP / laravel入門

Nothing worth to see here

あくまでも自分用のメモ

引き続きドットインストールのお世話になります。
今回はlaravelフレームワークのメモを残していきます。


メモ

Composer
laravelをインストールする上で、composerを使います。 依存性チェックツール。
JavaでいうMaven, Gradleにあたりますかね。
PHPはコンパイラ言語ではなくインタープリタ言語のため、build不要のはずです。
そのため、純粋に依存性のチェックと解決(必要なライブラリのインスト)だけだと思っています。
なぜ依存性チェックツールがlaravelのインストールの前に必要かというと、
laravelはフレームワークで多数のライブラリを必要とするため、
手動でライブラリの依存問題を解決するのは、やってられないからです。

composerのインストール
ろくに英語を読まずにやっていましたが、公式ドキュメントを参考に、下記のコマンドを実施しました。
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('SHA384', 'composer-setup.php') === \
'61069fe8c6436a4468d0371454cf38a812e451a14ab1691543f25a9627b97ff96d8753d92a00654c21e2212a5ae1ff36') \
{ echo 'Installer verified'; } else { echo 'Installer corrupt'; \
unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php --install-dir=/usr/bin --filename=composer
php -r "unlink('composer-setup.php');"
結果として、/usr/bin/composerが配置されます。 通常、/usr/binにはパスは通っているかと思いますので、基本的にcomposerと打てばどこからでも実行できるようになります。

php artisan --version
laravelのバージョン確認
結果
Laravel Framework version 5.3.28

laravelプロジェクトの作成
composer create-project --prefer-dist laravel/laravel
これでプロジェクトを作成できます。

.env
設定ファイル
まずは、下記3つの項目を更新する。
  1. DB
  2. USER NAME
  3. PW

config/app.php
envヘルパー
'log' => env('APP_LOG', 'single')
と言うやつ。
env()で.envから'APP_LOG'keyがkeyとして設定されている値を返します。
設定されていない場合は、二つ目の引数('single')が設定されるそうです。

config/app.php : 設定項目
'timezone' => 'Asia/Tokyo'
'locale' => 'ja'

yumコマンドのエラー
[vagrant@localhost myblog]$ yum install tree
Failed to set locale, defaulting to C
??????????:fastestmirror
自分の自己解決能力のなさを呪いながらも、Qiitaの記事でFIXしました。
localeがセットできないというエラー。
/etc/sysconfig/i18nにLC_CTYPE="ja_JP.UTF-8"を足す。

Httpセッションの管理系ソースを置くフォルダ
</Project Base Dir>/app/Http/
[vagrant@localhost myblog]$ tree app/Http/
app/Http/
├── Controllers
│   ├── Auth
│   │   ├── ForgotPasswordController.php
│   │   ├── LoginController.php
│   │   ├── RegisterController.php
│   │   └── ResetPasswordController.php
│   └── Controller.php
├── Kernel.php
└── Middleware
    ├── EncryptCookies.php
    ├── RedirectIfAuthenticated.php
    └── VerifyCsrfToken.php

routingを管理するファイル
laravel 5.3ではroute/web.phpでroutingを管理
[vagrant@localhost myblog]$ tree routes/
routes/
├── api.php
├── console.php
└── web.php

View関連を格納するディレクトリ
</Project Base Dir>/resources/Views
[vagrant@localhost myblog]$ tree resources/
resources/
├── assets
├── lang
└── views
    ├── errors
    │   └── 503.blade.php
    ├── vendor
    └── welcome.blade.php

php artisan make:migration <Migration Name>
まだ理解できていないのですが、マイグレーションファイルがこれでできる。
artisanファイルは、laravelのBase Dir直下にありますので、
Base Dirで上記のコマンドを実行しましょう。
 php artisan make:migration create_posts_table --create=posts
Created Migration: 2016_12_28_145157_create_posts_table
これでpostsというテーブルを作るバッチファイル(2016_12_28_145157_create_posts_table)が、
</Project Base Dir>/database/migrationsディレクトリ配下にできます。

マイグレーションファイル
作成直後のファイルのベタ貼り
increments('id');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}
up()にテーブル作成の処理、down()にテーブル削除の処理を書いていくとのこと。
テーブル削除も外部キーあると面倒くさかったりしますもんね。

Blueprintクラスのメソッド
  • increments : int unsigned not null auto_increment primary key
  • string : varchar(255) not null
  • text : text not null

マイグレーションファイルの実行
 php artisan migrate
 Migrated: 2016_12_28_145157_create_posts_table

既存テーブルに変更を加えるマイグレーションファイルの作成
php artisan make:migration modification --table=posts
新規作成ではなく、既存テーブルの変更の場合は--tableオプションを使用します。
基本的に--createで作ったファイルと同じですが、
up()/down()それぞれにある、Schema::tableメソッドは未実装です。

php artisan make:status
どのマイグレーションファイルが適用されているかを出力する

マイグレーションファイル実行のロールバック
php artisan migrate:rollback
Rolled back: 2016_12_28_153233_add_summary2
最後に実行したマイグレーションファイルのdown()が実行される模様。便利!

マイグレーションファイル実行のロールバック
php artisan migrate:rollback
Rolled back: 2016_12_28_153233_add_summary2
最後に実行したマイグレーションファイルのdown()が実行される模様。便利!

マイグレーションファイル実行のロールバックで「Class xxx not found」が出た時
composer dump-autoload
Generating autoload files
composerにパスが通っている前提です。

モデル作成用マイグレーションファイルの作成
php artisan make:model Comment
Model created successfully.
appディレクトリ配下にComment.phpができます。

対話的にモデルを通してDBにモデルの構造のレコードを挿入する
tinkerというプログラムを呼ぶ
 php artisan tinker
Psy Shell v0.8.0 (PHP 5.6.29 — cli) by Justin Hileman
>>> $comment = new App\Comment();
=> App\Post {#674}
>>> $comment->title = 'title 1';
=> "title 1"
>>> $comment->body = 'body 1';
=> "body 1"
>>> $comment->save();
=> true
>>> 

tinkerの終了
exit

Mass Assignmentってなんやねん。
答えはスタックオーバーフローにある
冒頭の数行しか読んでないですが、、、、
配列を使った、複数プロパティ(ORMしているからレコードのフィールドと同義)への代入のことですね。
Mass = 大量の, Assignment = 割り当て
ですもんね。
便利ではあるけど、セキュリティホールになるので、laravelはデフォがオフです。
個別に許可を設定する必要があります。

tinkerでstaticメソッドのcreate()を使いDBにモデルの構造のレコードを挿入する
create()メソッドを使って、連想配列を使ってレコードを挿入する。
しかし、前項目で書いた通り、先にMass Assignmentの設定をモデルクラスでする必要があります。
設定しないと下記のエラーが出ます。
>>> App\Comment::create(['title'=>'title 2', 'body'=>'body 2']);
Illuminate\Database\Eloquent\MassAssignmentException with message 'title'

モデルクラスでプロパティにfillableを設定します。
Mass Assignmentを許可するカラム名を配列で設定します。
protected $fillable = [ 'title', 'body'];

Mass Assignmentの設定をしたら、tinkerを再度立ち上げて、createメソッドを実行します。
連想配列の形で、複数カラムに値を設定できます。便利。
>>> App\Comment::create(['title'=>'title 3', 'body'=>'body 3']);

2016年12月27日火曜日

MySQLとPHP/基本のメモ3

前回まではとりあえず書いてみたっていうだけでした。
今回は、ここのメソッドや変数について確認します。


メモ

カウンタ変数に色をついた名前を
文法関係や言語に関係なく、なかなか治らない自分の悪癖
同時にカウンタ変数にアクセスされる場合や、
後で放置されたカウント変数にアクセスしちゃう場合があり得るんですね。
エラーになってくれた方が、論理エラーがなくなって助かりますが。。。

ローカル変数をグローバルに
用途がよくわからないのですが、、、できるようです。
global $変数名;
宣言時にglobal とつけてやる。

クロージャ(無名関数)
最近全然JS書いてないけど、スコープを作るために
無名関数書くっていうのもありますよね。

クラス内の定数
const 定数名 = 値;
グローバルな定数とは書き方が違う。
しかも$マークは付けない。
自クラス内で使う場合は、self::定数名
Javaでのstaticと同じような扱いか。

PHP 5.3 以降のconst
クラスの定数かどうかに関わりなく、定数宣言にconstが使えるそうです。
同じかと思ったら、下記の違いがありました。
constで定義したクラス外の定数 = 名前空間に属する
defineで定義した定数 = グローバルな定数

変数名と定数名と関数名
1文字目 = _または半角英字
2文字目以降 = _と 半角英数字
大文字・小文字を区別する。
※関数名のみ大文字・小文字を区別しない
※そうは言っても「書いた通りの大文字小文字で呼出せよ」と公式ドキュメントには書いてある。

PHPのfor文は変化式を複数かける
まぁforのスコープの中で増やしている処理がすっきり書けるっていうだけですが、
for ( $i = 0 ; $i < 0 ; $i++ , $countDown-- )
という書き方が可能。カンマ区切りで複数の処理を書くことができます。

PHP は関数のオーバーロードをサポートしていません。
公式ドキュメント
Qiitaの記事で紹介されていますが、
実装でカバーできるようです。

NULLとNULL文字(\0・NUL)は同義ではない
NULL文字(\0)の存在を初めて知りました。
文字列の終端を表すための文字なんですね。
一方NULLは何も参照していないことを表す記号ですね。

100-200回を超える再帰呼び出しはするな
これも公式ドキュメントネタです。
Paizaさんみたいなコードクイズでもない限り、自分は再帰処理を滅多に書きませんが、
メモリがスタックする可能性があることは記憶の片隅に留めたい。

PHPの変数は値を格納する「箱」not label
変数Aに変数Bを代入する場合、変数Bの値をコピーするということになる
$a = 10;
$b = $a;
$b = 20;
最後に$bに20を代入しているけど、$aの値は10のまま

逆に2つの変数を連動したい場合
参照を渡してみる
複数回メソッドを呼び出す際や、スコープをまたいで値を変更してあげたいときに
参照渡しを使う
&アンパサンダをつける。 変数の初期化
$a = 10;
$b =& $a;
$b = 20;
最後に$bに20を代入すると、$aも20となる

変数の初期化
 function doubleUp(&$num) {
   $num *= 2;
 }

 $age = 20;
 doubleUp($age);

doubleUpを呼ぶと、引数に渡した変数が倍に設定される。

アクセス修飾子(再掲)
デフォルトなんだったか忘れる。。。。publicですね。
public, protected, private
privateは自クラスのみアクセス可、子クラスからもアクセス不可。
protectedは自クラスと子クラスからアクセス可。
publicはどこからでもアクセス可
varを使ってプロパティを宣言した場合や、メソッドにアクセス権を明記しない場合は、public扱いです。

UTF8 BOM
BOMとか初めて知った。。。
Byte Order Mark
符号化に関するファイルヘッダーで、これが付いていることにより、 想定外の動作になることがあるらしい。

PDO_DSN
DSNはData Source Nameの略みたいです。
詳しくは公式ドキュメント参照ですが、
mysql:host=xxx;port=xx;dbname=xxx
というようにsql名:key=value;..で組み立てた文字列を使う。

PDO::setAttribute
属性の設定
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
で、エラー時に例外を投げる設定になる。その他は公式参照。

PDO::setAttribute( ATTR_EMULATE_PREPARES, false )
属性の設定
SQLインジェクション対策として、常にfalseにしましょう
で、エラー時に例外を投げる設定になる。その他は公式参照。
また、true担っているとDBでint型のものをStringに変換してしまうとか。。。
Qiita PDOでATTR_EMULATE_PREPARESを適切に設定してないとSQLインジェクションの原因になるかも(MySQL編)
参照:なんでPHPはMySQLからのリザルトがint型のはずなのにstring型になってしまうん?

MySQLとPHP/基本のメモ2

続きです。


メモ

ユーザ一覧表示
> SELECT user, host FROM mysql.user;
前回も載せたんですけどね。覚えてなかったので。
mysqlというシステム用のスキーマがあり、そこにuserテーブルがあると。

ユーザの削除
> drop user dbuser@localhost;

PHP Data Objects(PDO)
PHPでDBへつなぐ時のインターフェース。コネクターのことかな。

変数名の_アンダースコア
人気があるコーディング規約
プロパティの変数名の頭に_をつけることで、thisをつけなくても(つけ忘れても)
プロパティとわかりやすくする。また、そうすることで変数名の重複を減らすことができる。

ヒアドキュメント内の変数
展開される
シェルスクリプトとはちがうみたい

define('key' , 'value);
定数の設定。Javaと違いすぎて忘れる。

PDOのテンプレ
まず、DB名やユーザ名・PWを定数定義するとして、
try {
  // connect
  $db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
  $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

  // proc
  $db->exec("insert into users (name,score) values ('hoge', 5);");
  echo "user added!";


} catch (PDOException $e) {
  echo $e->getMessage();
  exit;
}

error
SQLSTATE[42000]: Syntax error or access violation: 
1064 You have an error in your SQL syntax; 
check the manual that corresponds to your MySQL server version 
for the right syntax to use near 
'insert555 into users (name,score) values ('tag', 5)' at line 1

preppare()
複数回使うクエリに適している。SQLインジェクションの対策が必要。
  $stmt = $db->prepare("insert into users ( name , score ) values ( ? , ? );");
  $stmt->execute(['hoge', 100]);
  echo "insert no : " . $db->lastInsertId();

exec()
結果を返さないで実行する。selectなど。
安全なクエリに使う。

query()
結果を返す。
安全、かつ、一度しか実行されないようなクエリに使う。
下記の例は2次元配列として格納されるようです。(3つの要素を持つ連想配列の配列)
  $stmt = $db->query("select * from users");
  $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
query()の結果は、PDOStatement オブジェクトが返ります。 詳しいことはQiitaのこの記事を読んでください。

$db->lastInsertId();
最後に挿入されたレコードのIDを返します。

名前付きパラメータ
「:パラメータ名」とすることで連想配列みたいに扱える。
  $stmt = $db->prepare("insert into users ( name , score ) values ( :name , :score );");
  $stmt->execute([':name'=>'hoge', 'score'=>100]);
:を付けても付けなくてもアクセスできました

bindValue()
プレースホルダーに値を保持させたままにすることができる。
下記の例だと$nameは変えてないので、hogeでちがうscoreのレコードを2行挿入できる。
  $stmt = $db->prepare("insert into users ( name , score ) values ( ? , ? );");

  $name = 'hoge';
  $stmt->bindValue(1, $name, PDO::PARAM_STR);
  $score = 43;
  $stmt->bindValue(2, $score, PDO::PARAM_INT);
  $stmt->execute(); // 1st
  $score = 55;
  $stmt->bindValue(2, $score, PDO::PARAM_INT);
  $stmt->execute(); // 2nd


プレースホルダーに名前を付けるとこうなる。
  $stmt = $db->prepare("insert into users ( name , score ) values ( :name , :score );");

  $name = 'hoge';
  $stmt->bindValue('name', $name, PDO::PARAM_STR);
  $score = 43;
  $stmt->bindValue('score', $score, PDO::PARAM_INT);
  $stmt->execute(); // 1st
  $score = 55;
  $stmt->bindValue('score', $score, PDO::PARAM_INT);
  $stmt->execute(); // 2nd

その他のデータ型
PDO::PARAM_NULL
PDO::PARAM_BOOL

bindParam();
プレースホルダーが参照する変数を固定する
  $stmt = $db->prepare("insert into users ( name , score ) values ( :name , :score );");

  $name = 'hoge';
  $stmt->bindValue('name', $name, PDO::PARAM_STR);

  $stmt->bindParam('score', $score, PDO::PARAM_INT);
  $score = 100;
  $stmt->execute();
  $score = 400;
  $stmt->execute();

FETCH_CLASS
PDOオブジェクトをクラスに代入する
Userクラスを作った上で、FETCH_CLASSするとオブジェクトを配列で返す。
class User {
# public $id;
# public $name;
# public $score;
  public function show() {
    echo "$this->name ($this->score) <br>\n";
  }
}

  $stmt = $db->query("select * from users");
  $users = $stmt->fetchAll(PDO::FETCH_CLASS, 'User');
プロパティは書かなくても、PDOのフィールドが勝手に保持されるみたいです。
楽だけどバグに気づかなそうなので、明示すべきですかね。

$stmt->rowCount()
PDOオブジェクトが持つ行数(要素数)を返す。

$db-beginTransaction();
トランザクション開始

$db->commit();
トランザクション終了

$db->rollback();
ロールバック
PDOExceptionをキャッチさせて使う。

2016年12月25日日曜日

MySQL/基本のメモ

PHPの基礎文法をおさらいできたところでMySQLも基本を振り返ってみます。


メモ

ログイン
$ mysql -u USER [-p]
-pを入れるとパスワードを入力することができる。

ログアウト
> exit;
OR
> \q

ヘルプ
\h OR help

標準入力のクリア
\c

DBの作成と作業ユーザへの権限付与
> set password for root@localhost=password('xxx'); -- rootユーザのパスワード設定
> create database store; -- DBの作成
> show databases; -- DBの一覧表示
> grant all on store.* to dbuser@localhost identified by 'xxx'; -- 作業ユーザの作成と権限付与
> SELECT user, host FROM mysql.user; -- ユーザ一覧表示
> use store; -- DBへの接続

テーブルの作成
> create table users (
-> id int,
-> name varchar(255),
-> email varchar(255),
-> password char(32),
-> score double,
-> sex enum('male', 'female'),
-> memo text,
-> created datetime
-> ); -- table作成
> show tables; -- table一覧表示

テーブルのコピー
> create table new_users like users; -- テーブル名だけ違う、同じ構造のテーブルを作成

NULL制約
id int not null

UNIQ制約
email varchar(255) unique

連番
id int auto_increment
連番を振るカラムにはインデックスを張る必要がある。
その際、primary key / keyのどちらでも問題ない。

default
score double default 0.0

主キー
id int primary key

主キーでないところにインデックスを貼る
key score (score)

tableのインデックスの確認
> show indexes from TABLE_NAME;

tableの構造を表示
desc[ribe] TABLE_NAME;

列の追加
> alter table users add created datetime default CURRENT_TIMESTAMP ;

indexの追加
> alter table users add index name(name);
インデックス名(カラム名)

indexの削除
> alter table users rename system_users;

tableのリネーム
> alter table users drop index name;

DBの削除
> drop database store; -- DBの削除

扱えるデータ型
  • 数値:int, double
  • 文字列:char, varchar, text
  • 日付:date, datetime
  • その他:enum

レコードを帳票形式(項目を横ではなく縦に並べる方式)で出力する
select * from users \G
\Gで文が終わるみたいです。;セミコロンを続けて末尾に入れたら、空行だと怒られた。
select * from users \G;
ズラズラ
...
ERROR:
No query specified

limit / offset。上から2行を無視し、3行取得。
「limit 3 offset 2」「limit 2 ,3」のどちらでもいい。
パラメータが逆になるので注意

外部ファイルからSQLを実行
$ mysql -u dbuser -p store < dataInit.sql

バックアップファイルの作成
$ mysqldump -u dbuser -p store > store.bu.dump

バックアップファイルからの復元
$ mysql -u dbuser -p store < store.bu.dump

カジノIR法 / まぁ仕方がないんじゃない

カジノについては私は容認派です。
自身はギャンブルやりませんが、国が稼ぐ手段は多い方がいいでしょう、というだけの理由です。

民間事業者にしてみればビッグチャンスで、どんなに政府が規制したとしても、
問題が全く起きないということはない、とは思います。
少し時間かけてでも問題が小さくなるようにしてもらえれば思うぐらいです。

ところで政府のギャンブル依存症調査の対象者は2,200人ほどらしいのですが、統計的には十分なのか。。。

なお、政府のギャンブル依存症調査の設計は、対象者は全国の成人2,200人ほど、設問は100項目で、ギャンブルの経験や生活への影響など。家庭への影響も検討を含む。
参照:カジノIRジャパン

PHP/printf/sprintf

PHPの基礎固めとして、PaizaのDランク問題を解きまくっています。
昔書いたコードを見て、少しだけ成長したなと感じたことを書きます。

お題としては、「1-3桁の数字が標準入力されるので、3桁ゼロ詰めで出力してください」

普通はこう書く

<?php printf (  "%03d",trim( fgets(STDIN) )  )?>

2016年3月ごろ書いたのがこちら

<?php
    $input_lines = fgets(STDIN);
    if($input_lines == 100){
        echo $input_lines;
    }elseif($input_lines > 9){
        echo "0".$input_lines;
    }else{
        echo "00".$input_lines;
    }
?>
車輪の再発明とはこのことですかね。無知は怖い。

printfとsprintf

sprintfは第1引数に変数を取れる。

PHP/配列の基礎

引き続き、初歩的な部分のおさらいです。



初期化
$array = array("hoge", "fuga")

print_r($array)
配列の中身をわかりやすく出力する
Array
(
  [0] => hoge
  [1] => fuga
)

$array[0]
配列の要素を返す

echo $array
間違った使いたで、Arrayと出力される。「Array to string conversion」warningが出る

array_push($array , "xxx") or $array[] = "xxx"
配列の末尾に要素を追加する。要素数は柔軟に変更される。
array_pop(), array_shift(), array_unshift()といった関数もある

要素数の上限
PHP4系=>65536個まで,PHP5系=>4294967296個まで
つまり、 PHP4系=>16bit個まで,PHP5系=>32bit個まで

要素の型
何でもいい。
サクッとサンプルプログラムを書く分には楽なんですが、大規模開発時の変数管理や処理速度はどうなのだろうか。。。

count($array)
要素の個数を返す

配列の要素の削除
unset($array[2])
後ろに要素があった場合でも、要素番号は繰り上がらない。
この場合、count()関数の返り値と配列の最大要素番号は関連性がなくなる。

explode("区切り文字", "文字列")
文字列を区切り文字で分割した配列を返す
メールアドレスチェックなんかで、@で分割して要素数が2か判定という使い方もできるか。
しかし、調べてみると、[mb_]substr_count("被検索文字列" , "検索文字列")という関数の方がわかりやすそうでした。

空行を含む入力の読み込み
<?php
while( $input = fgets(STDIN) ) {
    // 配列に$inputの値を追加
    $array[] = trim($input);
}
print_r($array);
?>

添字を連番で振り直す
array_values / array_merge

配列の並び替え
sort / rsort
配列のvalueのソートです。
連想配列に対して、このメソッドを使うとただの配列になってしまうので注意

日本語のソート
「ひらがな、カタカナ、漢字、全角数字」の順らしい
言われてみれば当たり前ですが、漢字のソートは読み仮名ではなく、文字コード順

asort / arsort / ksort / krsort
連想配列の配列
asort / arsort => valueの並び替え
ksrot / krsrot => keyの並び替え

foreach ( $array as $value)
あえていうほどでもないforeach

foreach ( $array as $key => $value)
keyも取得したい場合

PHP/JavaとPHPのhazardousな違い/変数のスコープ

関数内の変数がローカル変数になるだけで、for/while/ifの中でもグローバルスコープなんですね。
また、includeやrequireの中でも先に宣言した変数にアクセスできるとのこと。

一時変数やカウンタ変数の命名や初期化はきっちりやろうと改めて認識しました。

PHP/わかっていなかった空文字判定

途中に空行を含む標準入力を最後まで読み込む、というのをwhile/fgets(STDIN)/trimで書こうとしたら少しハマった。

こんな標準入力だと仮定して
0

hoge
結局、下記のように書いてFix
<?php
// 標準入力から1行データを取得
$input = fgets(STDIN);
// $inputの値が空で無ければループする
while( $input != "" ) {
    // 配列に$inputの値を追加
    $array[] = trim($input);
    // 標準入力から1行データを取得
    $input = fgets(STDIN);
}
print_r($array);
?>
追記
while ( $input != "" ) でなくて、while ( $input ) であれば十分でした。。。
trimしないことで、改行コードが残るんで。

注意点
  • 「改行コード」をtrimして変数に代入した場合、その変数は定義済みだが「空」であること(nullじゃない)
  • 判定前にtrimしてしまうと改行コードも空に成ってしまい、データがないことによる「空」と区別がつかない
  • 配列に改行コードは入れたくない

こちらのサイトを参考にさせてもらいました。
Allied ArchitectsEngineer Blog 空文字とかNULLとか0とか


おまけ

自分でも少し検証してみました。
まぁ、そうなりますよね。

結果
"0"
if ( $a ) : false
if ( $a == "" ) : false
if ( $a === "" ) : false
if ( is_null($a) ) : false
*******************************
null
if ( $a ) : false
if ( $a == "" ) : true
if ( $a === "" ) : false
if ( is_null($a) ) : true
*******************************
trim("\n")
if ( $a ) : false
if ( $a == "" ) : true
if ( $a === "" ) : true
if ( is_null($a) ) : false
*******************************
""
if ( $a ) : false
if ( $a == "" ) : true
if ( $a === "" ) : true
if ( is_null($a) ) : false
*******************************
"\n"
if ( $a ) : true
if ( $a == "" ) : false
if ( $a === "" ) : false
if ( is_null($a) ) : false
*******************************
0
if ( $a ) : false
if ( $a == "" ) : true
if ( $a === "" ) : false
if ( is_null($a) ) : false
コード

$a = "0";
echo "\"0\""."\n";
if ( $a ) {
    echo "if ( \$a ) : true\n";
} else {
    echo "if ( \$a ) : false\n";
}

if ( $a == "") {
    echo "if ( \$a == \"\" ) : true\n";
} else {
    echo "if ( \$a == \"\" ) : false\n";
}

if ( $a === "") {
    echo "if ( \$a === \"\" ) : true\n";
} else {
    echo "if ( \$a === \"\" ) : false\n";
}

if ( is_null($a) ) {
    echo "if ( is_null(\$a) ) : true\n";
} else {
    echo "if ( is_null(\$a) ) : false\n";
}

echo "*******************************\n";

$a = null;
echo "null"."\n";
if ( $a ) {
    echo "if ( \$a ) : true\n";
} else {
    echo "if ( \$a ) : false\n";
}

if ( $a == "") {
    echo "if ( \$a == \"\" ) : true\n";
} else {
    echo "if ( \$a == \"\" ) : false\n";
}

if ( $a === "") {
    echo "if ( \$a === \"\" ) : true\n";
} else {
    echo "if ( \$a === \"\" ) : false\n";
}


if ( is_null($a) ) {
    echo "if ( is_null(\$a) ) : true\n";
} else {
    echo "if ( is_null(\$a) ) : false\n";
}


echo "*******************************\n";


// $a = "";
$a = trim("\n");
echo "trim(\"\\n\")"."\n";
if ( $a ) {
    echo "if ( \$a ) : true\n";
} else {
    echo "if ( \$a ) : false\n";
}

if ( $a == "") {
    echo "if ( \$a == \"\" ) : true\n";
} else {
    echo "if ( \$a == \"\" ) : false\n";
}

if ( $a === "") {
    echo "if ( \$a === \"\" ) : true\n";
} else {
    echo "if ( \$a === \"\" ) : false\n";
}

if ( is_null($a) ) {
    echo "if ( is_null(\$a) ) : true\n";
} else {
    echo "if ( is_null(\$a) ) : false\n";
}


echo "*******************************\n";


$a = "";
echo "\"\""."\n";
if ( $a ) {
    echo "if ( \$a ) : true\n";
} else {
    echo "if ( \$a ) : false\n";
}

if ( $a == "") {
    echo "if ( \$a == \"\" ) : true\n";
} else {
    echo "if ( \$a == \"\" ) : false\n";
}

if ( $a === "") {
    echo "if ( \$a === \"\" ) : true\n";
} else {
    echo "if ( \$a === \"\" ) : false\n";
}

if ( is_null($a) ) {
    echo "if ( is_null(\$a) ) : true\n";
} else {
    echo "if ( is_null(\$a) ) : false\n";
}

echo "*******************************\n";


$a = "\n";
echo "\"\\n\""."\n";
if ( $a ) {
    echo "if ( \$a ) : true\n";
} else {
    echo "if ( \$a ) : false\n";
}

if ( $a == "") {
    echo "if ( \$a == \"\" ) : true\n";
} else {
    echo "if ( \$a == \"\" ) : false\n";
}

if ( $a === "") {
    echo "if ( \$a === \"\" ) : true\n";
} else {
    echo "if ( \$a === \"\" ) : false\n";
}

if ( is_null($a) ) {
    echo "if ( is_null(\$a) ) : true\n";
} else {
    echo "if ( is_null(\$a) ) : false\n";
}


echo "*******************************\n";


$a = 0;
echo "0"."\n";
if ( $a ) {
    echo "if ( \$a ) : true\n";
} else {
    echo "if ( \$a ) : false\n";
}

if ( $a == "") {
    echo "if ( \$a == \"\" ) : true\n";
} else {
    echo "if ( \$a == \"\" ) : false\n";
}

if ( $a === "") {
    echo "if ( \$a === \"\" ) : true\n";
} else {
    echo "if ( \$a === \"\" ) : false\n";
}

if ( is_null($a) ) {
    echo "if ( is_null(\$a) ) : true\n";
} else {
    echo "if ( is_null(\$a) ) : false\n";
}


?>

2016年12月24日土曜日

PHP/再帰処理関数

for文ばかり書くのも芸がないので、滅多に書かない再帰処理を関数で書いてみました。
お題は、「ある数の対数log2を求める」です。
配列の要素数の上限見ていたら、「これ何bitやっけ?」と思ったのがお題のきっかけです。


<?php
function devide($target)
{
    return $target / 2;
}
$target = 4294967296;
$count = 0;
while ($target > 1) {
    $target = devide($target);
    $count++;
} 
echo $count;
?>

再帰処理関数
<?php
function hoge(&$target, &$count) {
  if ( $target > 1 ) {
    $count++;
    $target/=2;
    hoge($target, $count);
  } 
  return $count;
}
$target = 4294967296;
$count  = 0;
echo hoge($target, $count);
?>

下記のブログエントリーを参考にさせていただきました。
by shigemk2 「PHPで再帰関数を作る」

PHP/コードゴルフ/1〜20までの数字を出力

めっちゃ簡単なお題ですが、コードゴルフもどきです。

「1〜20までの数字を出力」をできるだけ短く書く

普通に書くと、これですよね。

<?php
$i = 1;
while ( $i <= 20 ) {
    echo $i."\n";
    $i++;
}
?>

下記の特徴を活かして省略します。

  • PHPは変数を宣言せずに使える(動的型付け言語)
  • while文を{}ブロックなしで書くことができる(みたい)
  • 前置インクリメントが使える

デン

<?php while ($i<20) echo ++$i."\n";?>

PHP/trim/文字列の先頭・末尾の空白や改行の除去

あえて書くほどでものない関数
改行も除いてくれるんですね。

rtrim, ltrimもあります。
chopはrtrimのエイリアスで非推奨とのこと。

PHP/フレームワーク/laravelにすべきかSymfonyにすべきか

記事書いてて結論が出ました。
PHPのフレームワークはどれを勉強するか迷っていましたが、laravelやります!
ただ、なぜlaravelが最近人気出ているのか、他のフレームワークとの差分はもうちょっと調べます。

PHPはフレームワークが多いって話は聞いていましたが、調べてみると本当に多いですね。
下記の記事で、8個リストアップされていました。
Qiita メモ書きPHPフレームワーク一覧

自分でもGoogle Trendsを使って確認してみました。
laravel人気ですね。
過去1年の日本でのトレンドです。

先日、何も考えずにPHPの本を1冊購入したのですが、
こちらの本ではSymfonyを使っていました。

改めて、Google Trendsを過去5年間に引き伸ばしたところ、下記のような趨勢でした。

  • 2011年頃 :SymfonyとCodeIgniterが2強として競う
  • 2013年頃 :FuelPHPの検索数がSymfonyとCodeIgniterを上回る
  • 2014年末頃:laravelの検索数がFuelPHPと並ぶ
  • 2016年  :FuelPHPの検索数がガクッと落ちてlaravel一人勝ち状態が始まり、今に至る

人気が出ているものが素晴らしいとは限らず、
すべての言語・フレームワークは一長一短だと思いますが、
息の長いテクノロジーに乗っかりたいのでlaravelを勉強することにします。

PHP/strpos/文字列内の部分文字列が最初に現れる場所を見つける

部分一致している最初の文字位置を返す。
最初の位置はゼロ。(1なのってSQLぐらいか。。。)

Qiitaで良い記事がありました。
部分一致があるかの判定でstrposを使う場合、==ではなく===を使い、型判定まで使う必要があります。
※参照:Qiita 【PHP】特定の文字列を含むかのチェック

これはもし文の最初で一致していた場合、strposからはゼロが返ってきます。
つまり、「abcにaが含まれていない時」を表現しようと
strpos('abc' , 'a') == false とかいた場合、
0 == false となり、ゼロはfalseと同意なので
false == false (0 == 0なのかな?)のように最終的に比較され
true という結果になる、みたいです。「abcにaが含まれている」のに実行されてしまいます。

無理くりまとめると、

部分一致している時に実行 :strpos('abc' , 'a') !== false
部分一致していない時に実行:strpos('abc' , 'a') === false
と書きましょう

PHP/array_values/配列の全ての値を返す

この関数により、連想配列を普通の配列としたり、添字が飛んでいる配列の添字を振り直すことができるみたいです。

PHP/日付の取得

今年が西暦何年か「西暦year年」(yearは今年の西暦)と出力して下さい。

<?php
$year = date('Y');
echo '西暦'.$year.'年';
?>

date関数でした。。。
引数のフォーマットで日時を返します。
date('Y')

初めてのPHP 2

凡ミスはなくしたい。Javaでも共通のプログラミング初心者あるある。
自分ではこの段階は卒業したと思っています。

  • クォート内とコメント以外は全角文字不可
  • セミコロンとコロンの打ちまつがえ
  • 行末の;セミコロン忘れ

てっとり早いFixはIDEを使うこと。
スペース・タブ記号や行番号を表示させておきたい。

2016年12月23日金曜日

初めてのPHP


周りでPHPを始めた人がいたので、自分も乗っかってみました。
まずはドットインストールから入り、適当な書籍に移っていこうと思います。
ドットインストールのPHP入門講座を見てみたり、paizaでレベルDの超簡単な問題をPHPで書いたり、ドキュメントをググったりして得た気づきをリストアップします。



環境

  • 概要:MacOSにvagrant + virtual BOXでcent osを載っけてPHP5
  • Host OS: MacOS El Capitan 10.11.6
  • Guest OS:centos 6.6
  • PHP: 5.6.29
  • Vagrant: 1.9.1
  • Virtual Box:5.1.12



気づき

PHPの由来
SlideShare PHP基礎勉強会より引用
Hypertext Preprocessor(ハイパーテキストプリプロセッサー)
元々PHPは「Personal Home Page」(パーソナルホームページ)の略でしたが、1998年にリリースされたPHP3から意味が変更されました。

コメント
1行コメントは // , # どっちもいける
複数行は /* */

文末は;セミコロン
そのまんま

閉じタグ
PHPしか書かない時は、<?phpの閉じタグ(?>)は書かなくていい

php? PHP?
ロゴは小文字ですが、公式サイトの文章内ではPHPと大文字でした

ビルドインサーバを実行できる
ドキュメントルートに移動して、「php -S 192.168.33.10:8000」
アクセスログやエラーログが標準出力される。

メソッド名間違えただけでも HTTP Response Statusが500 Internal Server Errorになるみたい
試しにechoメソッドをechooにしてみてから、そのファイルにアクセスしたところ、
500 Internal Server Errorとなった。
テンプレートエンジンとは違い、シビアですね。

ログはわかりやすい。
[Fri Dec 23 10:59:32 2016] 192.168.33.1:59552 [500]:
 / - syntax error, unexpected '"hello from the TOP!"'
 (T_CONSTANT_ENCAPSED_STRING) in /home/vagrant/php_lessons/index.php on line 8
実際のindex.phpの8行目
 echoo "hello from the TOP!";

変数
変数の宣言およびアクセスは「$変数名」
アクセスする際は、「{$変数名}」も可
宣言に「$」をつけることを除けばシェルスクリプトと同じ。
動的型付け言語。変数宣言時に型の指定が不要。
perlみたいに条件判定は柔軟に行えるかな?

var_dump(変数)
変数の型を取得する

 $msg = "hello from the TOP!";
 var_dump($msg);

string(19) "hello from the TOP!"

定数
defineメソッドで定義する。
define(定数名, 値);

また、アプリケーションが持つ定数がある。
__LINE__(行数), __FILE__(ファイル名), __DIR__(ディレクトリ名)

**
PHP5.6からはべき乗の演算子が使える。
Javaだとpow()関数ですね。

単項演算子
インクリメントは前置も後置も対応している。
x++
++x

""'(ダブルクォート) , ''(シングルクォート)の文字列の扱いの違い
シェルスクリプトなんかと同じですが、""は変数を展開します。
一方、''は変数を展開せず、入力した値の通りに扱います。
また、特殊文字(\t, \n)も同じように""だと展開される。

文字列の連結
.(ドット)でつなげる。ここはperlと同じ。
.=(複合代入演算子)も大丈夫。

エルスイフはelseif
ここの表記は言語間で統一してくれ...

==, ===
JSでよく話題に上がるアレ
===だと型まで判定に含めるので、数値の1と文字列の1は別。
==だと数値の1も文字列の1も同じだと見なす。
Javaだと型を変換する必要があり面倒くさいから、ここら辺はPHPだと助かる。

標準入力
fgets(STDIN)で標準入力を取得できます。

False
文字列:空、"0"
数値: 0、0.0
論理値:false
配列: 要素の数がゼロ
null

True
文字列:(空、"0")以外
数値: (0、0.0)以外
論理値:true
配列: 要素の数が1以上

SWITCH句
文字列で分岐できる!
Javaじゃできん。

DO-WHILEだけ;が必要
CもJavaもPHPも、while句では;いらないけど、
do-whileだと;が必要なんですね。。。

連想配列と一般的な配列の区切りが少ない?
一般的な配列も、keyをゼロから連番で振っている連想配列だと考えることもできると気づきました。
要素の値を取り出す際は、配列名[添字またはkey名]

foreach ($arrays as $key => $value) { }
配列のkey-valueを取り出せる。
Java : for (int seiseki: data){ }
Javaだとオブジェクトも取り出せますね。
一方、PHPはオブジェクト取り出せないように見えますが、keyとvalueの取り出しがわかりやすい。
またPHPのforeachは、次のようにも書ける。
foreach ($colors as $values) :
  echo "$values\n";
endforeach;

function
JSか。。。
引数の初期値を設定できるのは斬新
function greet($word = "Hi"){ }
また、PHPは動的型付けなので、関数の戻り値も設定しないんですね。

スコープ
スコープ外の変数にアクセスしてもnullとなるだけ。
Javaみたいに例外でプログラムが止まったりしない。楽ですね。
まぁ見つけづらくなるというデメリットがありますが。

try-catch-finally句
PHP5.5以降でfinally対応。




セッション関連

ドットインストールやQiitaの記事( Cookieとセッションをちゃんと理解する )を参照しました。

クッキー

ブラウザが持つ
そのため改ざんが比較的容易
大きなデータは持てない

PHPセッション

HTTPセッションと紛らわしい。。。
サーバが持つ
そのため改ざんが比較的困難
大きなデータも持てる
$_SERVER['REQUEST_METHOD']
HTTP REQUESTの種類を取り出す

$_POST['パラメータ名']
bodyに含まれるパラメータの値を取り出す

htmlspecialchars(文字列, ENT_QUOTES, 文字コードを示す文字列)
文字列のエスケープ

setcookie("username", "hoge");
クッキーを保存する
同じブラウザの違うタブでもアクセスできる
第3引数に有効期間を設定できる(デフォルトはブラウザを閉じるまで)

$_COOKIE['キー']
クッキーを取り出す

session_start();
HTTPセッションをまたぐパラメータのやり取りを可能にする。
このsession_startのセッション(区別のため「PHPセッション」と呼ぶべきか)の
スコープ(生存期間)がよくわかっていない。

$_SESSION['パラメータ名']
HTTPセッション間でのパラメータ

unset($_SESSIN['パラメータ名'])
HTTPセッション間でのパラメータを破棄するメソッド




関数リスト

echo ""
文字列の出力

ceil($int);
切り捨て

floor($int);
切り上げ

round($int);
四捨五入

rand(1, 6);
引数1から、引数2までの整数をランダムに取得

strlen($str);
文字列の長さを返す
strlen(ネコ)が6で返ってきたので、びっくり。
全角文字は絶対2バイトだと勘違いしていましたが、調べたところ、UTF-8だと1-6バイトのいずれかになるらしいです。

mb_strlen($str);
マルチバイト文字の文字列の長さを返す
mb_strlen(ネコ)は2です。
第2引数に文字コードを明記できます。

printf
お馴染みのフォーマット指定の出力

count(配列名)
要素の数を返す

implode("文字", 配列)
文字で、配列を連結した文字列を返す

explode("文字", 文字列);
implodeの逆
文字で、文字列を分割した配列を返す



クラスとインスタンス


だいたいJavaと同じっぽい。助かった。。。


コンストラクタ
__construct()と書く

メンバ
$this->変数と書く
※変数の前に$はつけない!

extends
継承。
Javaと同じく多重継承できない。
多重継承と同じ効果は、interfaceを通して実現する

final
子クラスで上書き不可を示す修飾子

public, protected, private, default
アクセス修飾子
privateは自クラスのみアクセス可、子クラスからもアクセス不可。
protectedは自クラスと子クラスからアクセス可。
publicはどこからでもアクセス可
公式ドキュメントには、「アクセス権 (visibility) 」と記載されている。
varを使ってプロパティを宣言した場合や、メソッドにアクセス権を明記しない場合は、public扱いです。

static
クラスをインスタンス化しないでアクセスできるようにする修飾子。
クラスメソッドの呼び出しは クラス名::メソッド()
クラスプロパティへのアクセスは、self::$プロパティ名

abstract
抽象クラスであることを示す修飾子




コードの分割

requireとrequire_onceの違いを調べてて、
PHPってインタプリタ言語なんだなって痛感しました。
Javaだとクラスファイルを書き分けるために、ソースコードを分ける場合がほとんどだと思います。
PHPだと、「一連の処理だけ別のファイルに書き出す」ってこともできるみたいです。
requireやincludeでファイルを読み込んだ時点で、その中の処理が実行される場合があるということです。
あと、「ファイルパスは絶対パスで書こう」意見を見つけました。
マコトのおもちゃ箱 ~ぼへぼへ自営業者の技術メモ~ 「PHP、require、includeする時の注意点。」
振り返ってみると、Javaのパッケージ読み込みはフルパスですね。
そういえば、PHPのIDEは何がpopularなのだろうか。。。
require
「君が絶対必要なんだ!」ということで、指定したファイルがなきゃ実行しない。(fatal error)

include
を含む。なかったら警告を出す。プログラムは止まらない。

require_once / include_once
同じファルは2回読み込まない。
アプリ全体でカウントするのか、特定の呼び出し元ファイル内だけでカウントするのかがわからない。
困った時に調べよう。

autoload
未定義のクラスについて、そのクラス名でファイルを探索して読み込む。
便利!

sql_autoload_register(function($class){
  require 
});
これで未定義のクラスについて、自動で読み込んでくれます。

クラスファイルを読み込み忘れた時
こんなエラーメッセージで怒られる。status 500。。。。
[Fri Dec 23 20:10:21 2016] 192.168.33.1:52369 [500]:
 / - Class 'User' not found in /home/vagrant/php_lessons/index.php on line 12

namespace hoge\Lib;
階層の区切りが\です。
<html>要素の中に書いたらダメ。
ファイルの冒頭にphpタグを入れて、その中に書く。

use 名前空間 as 別名;
名前空間に別名をつけることができる。



PHP IDEの考察

考察と言ってもググってTOP5の記事をブラウズしただけですが(^^;
自分が最も助かった記事はグーグル順位5位のこちらの記事でした。
BULBLUB WEBの仕事をしている建築士のブログ 「PHP向けIDEリスト[PHPSTORM, NETBEANS, APTANA STUDIO, ECLIPSE]」
個人的にEclipseを試してみます。
理由は2つあり、

  1. Javaでたまにお世話になっているので、UIに違和感がない
  2. 本当はPhpStromを使いたいが、メイン言語ではないPHPのIDEに$89は出せない
です

SQLインジェクション対策もれの責任を開発会社に問う判決 | 徳丸浩の日記

SQLインジェクション対策もれの責任を開発会社に問う判決 | 徳丸浩の日記


WEB+DBマガジンか、Software Designかどちらかの雑誌に載っていたので、直接ブログエントリーを読んでみました。


2009年4月15日のウェブサイト稼働開始時点ではクレジットカード情報を扱っていなかったことから、僕はこの判決は原告に甘すぎるのではないかと思いました。このウェブサイト向け商品受注システムがどのような商品を扱っているかはわかりませんが、初めはクレジットカードをサーバに格納しない状況だったので、セキュアなシステム要件を暗黙に認めるかというと微妙なのではと考えました。


一方、被告にまったく非がないかと言えば、非はあったようです。管理ユーザーIDPWがデフォルトでよく使われるもので、あまりセキュリティを意識していないような成果物だったようです。


この判決は、昨今のセキュリティへの問題意識の高まりを汲んだものではないかと、私は穿った見方をしています。何はともあれ、今後のシステム開発の現場では、IPAが発表しているセキュリティ対策やチェックは必須だと考えないといけないですね。

2016年12月21日水曜日

C言語を復習してみた

ドットインストールさん、お世話になっています。
周りにC言語を始めた方がいたので、ドットインストールを使って復習してみました。

気になった点だけメモする。

  • string型はないので、文字列はcharの配列
  • 文字列の終端は「\0」
  • 配列は、宣言と同時に初期化する場合は、要素数の指定不要(初期化した要素数となる)
  • ローカル変数にstaticをつけると、関数が終わっても値を保持する
  • Javaはcに似ている(if/for/while/switch)
  • コンパイルめんどくさい。。。
  • モジュールのインポートは#include
  • whileはブロックなのに対して、do-whileは文(do-whileの末尾にセミコロンが必要)
  • ポインタの宣言時には、名前の前に*をつける
  • 変数のアドレスを取り出す際は、変数名の前に&をつける(先頭のアドレス位置を取り出す)
  • ポインタ名の前に*をつけることで、ポインタに格納されているアドレスの位置、を示す領域が持つ値を取り出せる。

2016年12月17日土曜日

Java

コーディング力上げたいな。 もっというと、要件やテストケースの理解力が大事ですね。

Paizaさんのコンテンツで遊んでたけど、六村リオの緊急事態 (Bランク問題)のテストケース4で失敗する。。。悔しか。。。



/////////////////
// code
/////////////////
import java.util.*;

public class Main {
    public static void main(String[] args) {
        // 自分の得意な言語で
        // Let's チャレンジ!!
        Scanner sc = new Scanner(System.in);
        String line = sc.nextLine();
        String[] tempArray = line.split(" ", 0); 
        String[] currentDir = tempArray[0].split("/",0);
        ArrayList path = new ArrayList( Arrays.asList(currentDir) );
        String[] targetPath = tempArray[1].split("/",0);
        // System.out.println( Arrays.toString(currentDir) );
        // System.out.println( Arrays.toString(targetPath) );
        
        String output = "/";
        int position = path.size() - 1 ;
        // System.out.println(position);
        for ( String dir : targetPath ) {
            if ( dir.equals("..") ) {
                position =  ( position == 0 ) ? position : --position;
                
            } else if ( dir.equals(".") ) {
                continue;    
            } else if (  ! path.get( position ).equals(dir)  ) {
                path.add( position + 1  ,dir);
                position++;
            }
        }
        
        for ( int i = 1; i < position + 1  ; i++ ) {
            output += path.get(i) ;
            if ( i < position  ) {
                output += "/";
            }
        }
        System.out.println(output);
    }
}

MicrosoftもFlashと距離をおきますか。。。

マイナビニュース マイクロソフトもEdgeからFlashを排除の方向

HTML5によるコンテンツ配信がデフォルトですね

2016年12月10日土曜日

what3words

日本だと需要ないだろうけど、面白いサービス

全世界の住所を3x3meterで分割し、それぞれのブロックを英単語3語を組み合わせたURLで特定する。 ちなみに東京六本木は下記のURLになりました。
http://w3w.co/brittle.writings.coached

モンゴルの郵便公社がサービスを利用するのだとか
http://gigazine.net/news/20160626-mongolia-three-word-address/

2016年11月27日日曜日

i18n

'internationalization'のことを'i18n'と略すらしい。
由来は、初めの'i'から最後の'n'までの中に'18'文字'入って'いるからだとか。
確かに長いよね。

2016年11月23日水曜日

<Linux>uniqコマンドでソートする理由

最近、無知無能を実感します。$ cat file | sort | uniq ってしょっちゅう実行してたけど、なんでsortが必要か理解していなかった。
sortする必要性があるのは、uniqコマンドは隣接行しか確認しないからですね。sortしないと重複行が消えない。

man uniqの結果をベタ貼り

The uniq utility reads the specified input_file comparing adjacent lines, 
and writes a copy of each unique input line to the output_file.  

和訳してみた

uniqコマンドは隣接行を比較しつつ入力ファイルを読み込み、ユニークな入力行のコピーを出力ファイルに書き込みます。

標準出力なども、shellがuniqを実行して、ファイルをOSに渡して出力させているってことなのかな。
いつも「~コマンドを叩くと標準出力に..が出る」みたいな言い方をしてしまうけど、正確に言うと
「ターミナル→shell→OS→スクリーン」ですかね。

<Linux>chmod [u|g|o|a]<+|-><w|x|r> file

さすがにchmod +xはよく使うので、+とrwxはそれぞれの権限を付与するというのは知っている。

しかし、chmod u+x fileと書かれた時に、「?」となったので、メモとして投稿します。
パーミッションは、所有者ユーザー・グループ・その他のユーザにそれぞれ設定できて、
u+ / o- とパーミッションの付与・剥奪の対象を選択できる。
指定がなければ、a+ / a- と同じで全てに対して操作する。

2016年11月22日火曜日

<Linux>which -aなんて使ったことなかった。。。

何事もマニュアルや公式ドキュメント当たって調べてみるべきですね。
perlの本読んでたらwhich -a perlと載っていました。
whichコマンドにもオプションが存在していたって知らなかった。。。

-a オプションをつけると、引数に指定したコマンド(実行ファイル)の場所を全て列挙する。
javaなど、複数のバージョンの実行ファイルなどあった場合に、全てのファイルの位置が出るそうです。
デフォルトは一番初めのもののみ。

以下、自分の環境での man whichのベタ張りです。
NAME
     which -- locate a program file in the user's path

SYNOPSIS
     which [-as] program ...

DESCRIPTION
     The which utility takes a list of command names and searches 
     the path for each executable file that would be run had these commands actually been
     invoked.

     The following options are available:

     -a      List all instances of executables found (instead of just the first one of each).

     -s      No output, just return 0 if any of the executables are found, or 1 if none are found.

     Some shells may provide a builtin which command which is similar or identical to this utility.  
     Consult the builtin(1) manual page.

SEE ALSO
     builtin(1), csh(1), find(1), locate(1), whereis(1)

HISTORY
     The which command first appeared in FreeBSD 2.1.

AUTHORS
     The which utility was originally written in Perl and was contributed 
     by Wolfram Schneider .  The current version of which was
     rewritten in C by Daniel Papasian .

ちなみに、引数は複数取れるというのは今日初めて知りました。

$ which java perl
/usr/bin/java
/usr/bin/perl

2016年11月20日日曜日

<Java>printlnで出力される改行コード

勘違いしていたので、メモメモ...
「JavaのPrintStdeamクラスのprintlnメソッドで出力される改行コードは、OSにより異なる」

Write Once, Run everywhere.
というのがJavaの言語思想にあるってことは、わかってても、
\nがどのOSでも同じように解釈されるのかと、かんつがいしておりました。

そもそも\nと\rが意味することを理解していなかった。

改行コード略字英語日本語訳採用しているOS
\rCRCarrige Return復帰UNIX, Linux系, Mac OS
\nLFLine Feed改行(※紛らわしいので英語で読みたい)Windows
\r\nCR+LFCarrige Return + Line Feed旧Mac OS

2016年11月19日土曜日

<Java>BigDecimal

軽い投稿。
3年ぐらい前にOracle Java Programmer Certificationの試験を受けたことがありますが、その時にまったく勉強した記憶がなかったBigDecimal。
コンストラクタの引数は文字列として数字を書かないと、誤差が出てしまうんですね。

BigDecimal bd = new BigDecimal("1.0");

2016年11月13日日曜日

マウス分解してみた

タイトル通りマウスを分解してみた。
電気・回路は全然わかんないけど、とりあえずやってみようと。
これまでの分解経験は壊れた電子辞書ぐらいです。

今回のお相手は、こちら
iBUFFALO 無線(2.4GHz)光学式マウス 3ボタンタイプ ブルー BSMOW10BL

マウスホイールが付いているだけのワイヤレスマウスです。
シンプルで悪くなかったです。
しかしながら、前の会社にUSB受信機を置いてきてしまったので、お役御免になりました。。。

まず一番上のカバーを外します。

次に中蓋を外します。

開けてみるとネジで止めているみたいですが、裏から見てネジは見えなかった。
どうやって作ってるんでしょう?

反対側

針金は乾電池のプラス極とつながっているみたいです。
クリックした時につながっているスイッチはKailhというメーカーみたいです。

回路のCI3とかU3とかわかんないなぁ。暇になったら調べます。

核兵器禁止決議を採択 国連総会、日本は反対

核兵器禁止決議を採択 国連総会、日本は反対(日経新聞電子版)
核兵器禁止決議を採択(ニュースで英会話)
核禁止条約 交渉開始へ  国連委決議、日本反対(東京新聞)

いやはや、日本って面白いな。この決議に賛成できないとは。
軍事面ではアメリカと協調しているので、アメリカのアドバンテージを損なうこの決議には反対せざるをえない。

まず、核兵器があるべきかっていうと、下記の理由で核兵器は廃絶すべきだと思います。

  • 放射能汚染を伴う
  • 多数の民間人も犠牲になる


<採択への反応>

  • 棄権・・・中国、インドなど16カ国
  • 反対・・・米国、英国、フランス、ロシアなどの核保有国、38カ国
  • 賛成・・・核兵器を保有しないオーストリアやメキシコなど123か国

主要な国を見ている限り、核を持っていれば危険か反対、それ以外は賛成してますかね。
核兵器の抑止力が高いことや、制作・維持費用が高いことの裏返しでしょうか。

しかし、核の傘には入らないで、国の軍事的な安全を確保するのって難しそうだな。。。
国内で、ある程度地理的に分散させて軍備配置するとか、東南アジア・オセアニア諸国と友好関係を維持・構築してアメリカへの依存度を下げるとかですかね?自分でもどうすべきか全然わからないので、暇なときに考えます。

官僚の無謬性

バイリンガルニュースというポッドキャストを聞いていたら、マミさんがぽろっと話していた。
官僚は「自分たちは間違えを犯さない」という暗黙の前提を持っている、というのが官僚の無謬性です。

自己イメージ(エフィカシーとかいうだっけ?)というのはある程度大事だと思います。
ただ、「自分たちは間違えを犯さない」ということが全員の共通認識となり、それが組織の目的よりも優先されるような事態となったら、誤った行動をとるようになってしまうかもしれないですね。

2016年11月6日日曜日

GUのレジ

日進月歩。日々テクノジーは進化してきますね。
UNIQLOの姉妹ブランドであるGUで本日お買い物してきましたが、
セルフレジにびっくり。

いやセルフレジ自体は珍しくないのですが、
(東京大田区大森の西友さんで使ったことあるし、多分、多分コストコさんとか外資のスーパーは積極的に使ってるんとちゃう?)
GUのレジは、扉の中に買い物かごをおいてボタン押すだけで全ての商品を読み込んだんですよ!

というわけで、ググってみると、RFID(ICタグ)使ってるんですね。
(参考:GUのセルフレジを体感 時間短縮で満足度UP ファストリ)

「ユニクロ」などを展開するファーストリテイリングが、「ジーユー」の4店舗でセルフレジの試験運用を始めた。セルフレジはRFID(ICタグ)を活用したもので、購入者自身がハンガーなどを外して、レジ備え付けのボックスに商品を入れれば、より短時間で精算が可能になるという画期的なサービス。

〜中略〜

さらにタグには、商品を生産しないまま持ち出すとゲートでブザーが鳴る防犯機能もあり、万引などの犯罪の抑止効果もあるという。

〜中略〜

「ICタグは通常の値札よりも高価な上、1店舗当たり約4~5万枚が必要なため、この入れ替え費用はばかになりません。レジ自体も数百万円の初期費用が掛かるので、簡単に拡大することは今の段階では考えていません」と長谷リーダー。
ようは大きなくくりでいうと、SUICAなどと同じ技術を使っているということ。
(※ 細かい規格は違うかもしれない。。。type a, type b, felicaのどれなのかな)

商売の観点で面白いのは、自分が行ったGUは上野のジーユー御徒町店なのですが、
こちらはビルの5,6階に入っています。 同じビルの1-4階を占める、GUと同時にオープンしたユニクロ 御徒町店では、
レジはセルフではなく、通常のレジです。
UNIQLOブランドでの統一性の観点や、GUでの運営費の低減や万引き抑止の目的から、 セルフレジの導入はGUだけなのかと思っています。
参考記事の時系列から、ジーユー御徒町店は2014年4月25日の開店当時はセルフレジではなく、
2015年5月以降にセルフレジを導入した模様です。
そのことから費用に見合う効果は出ているのではないかと穿っています。

参考記事:

新聞読まないと。。。「ポケモンGO」による死亡事故で実刑判決

恥ずかしながら新聞読んでないので、ネットサーフィンしていてニュースにびっくりすることになる

「ポケモンGO」による死亡事故で実刑判決

こちらのシンク出版 という会社様のサイトでたまたま見かけました。
以下引用:

さる8月23日午後7時半ごろ、徳島市で軽ワゴン車を運転していた男性が「ポケモンGO」に気を取られたため、道路を横断していた女性2人に気づかずはねて1人を死亡させ、もう1人に重傷を負わせる事故がありました。

 この事故は、「ポケモンGO」による初めての死亡事故として話題になりましたが、このほど自動車運転処罰法違反の罪に問われた男性に対する判決があり、徳島地裁では禁錮1年2月(求刑禁錮1年8月)の実刑判決を言い渡しました。

 判決のなかで、裁判官は「『ながらスマホ』による前方不注視で、直線道路で被害者にまったく気づかない過失は非常に大きい。単純な過失とは一線を画する」と述べています。

 車を乗っているときには、当然前方の進路などを見て安全確認をしながら運転していますが、運転中にスマートフォンで「ポケモンGO」をするということは、明らかに安全確認をする意思がないということになり、こうした厳しい判決になったのだと思います。

 「ポケモンGO」に限らず、運転中はわき見運転につながるゲームは絶対にしないようにしてください。

引用終わり:
交通事故は確率的に起きるものですが、「ポケモンGO」はいただけないですね

スイスチーズモデル

そういえば、ヒューマンエラーに関する資料で見たことあるなぁという単語。
たまたまネットを漂っていたら目にしました。

ある望ましくない結果や事故に対して、1つの対策では抜け漏れが出る可能性はあるが、
複数の対策を重ねることで、いづれかの対策で発生を防ぐことができるという考えのことです。

2016年11月4日金曜日

<Linux>crontabってファイル読み込めるんですね

知らないことばかりですわ、全く

crontabコマンドってバックアップファイルから設定を反映することができるなんて。。。

今までおどおどcrontab -e やらcrontab -l を打っていたのがアホらしい。

manを読んでもしっかり書いてあるしね


SYNOPSIS
     crontab [-u user] file
     crontab [-u user] { -l | -r | -e }

DESCRIPTION
...
     The first form of this command is used to install a new crontab from some named file or standard input if
     the pseudo-filename `-' is given.

2016年11月3日木曜日

Wayback Machine

沈黙のWebマーケティング Webマーケッター ボーンの逆襲という本で紹介されていた、ウェブサイトの過去の状態を確認できるWebサービス。

試しにグーグルのURL入れてみたところ、毎日ストックされているみたいでした。
デザインの微妙な変化を確認できました。

Wayback Machine

2016年10月26日水曜日

<Java>EJBだとアクセス修飾子でコンパイルエラーにならない?

最近、プログラミングで困ったことをアップしておきます。

Stateless EJBから、同パッケージの別クラスのメソッドへのアクセス不可でもコンパイルエラーにはならなず、実行時エラーになる。

説明が難しいですね。。。
まず、アクセス修飾子についておさらいですが、
protectedが付与されたメンバには、自クラス・同パッケージ・サブクラスからアクセスできます。

Oracle The Java™ Tutorials Controlling Access to Members of a Class

antのビルドは通ったのですが、 実行時、stateless EJB bean からアクセスする際に下記のエラーが出ました。

java.lang.IllegalAccessError: tried to access method Connected.getString(Ljava/lang/String;)Ljava/sql/ResultSet; from class sample

先輩に教わりましたが、publicにすると問題なく実行できました。
protectedだから問題ないと思ってましたが、実行時のエラーから問題のあるメソッドは特定できていたので、試してみるべきでした。。。
同パッケージなのに、protectedでアクセスできないというのは、クラスローダーが違うからみたいです。 java EEのデバッグしんどい。。。

参照: stack overflow / java.lang.IllegalAccessError: tried to access method

テンションリダクション効果

本日は、広告業界・心理学用語です。

テンションリダクション効果

心理的に緊張している状態が続いた後に、ほっと一息ついた瞬間は注意力が落ちる、 というごくまっとうな傾向のことだそうです。

Amazonの「他の人はこれも見ています」、が一例です。

参照:
テンション・リダクションの効果と具体例。マーケティング応用
”無防備な状態”に付け込む心理学「テンション・リダクション効果」とは?【コピーライティング×心理学】

2016年10月22日土曜日

"Brave Shores" has a good vive !

<JavaScript>boolean以外の変数も判定できるんですね

自分のメイン言語はJavaのため、JavaScriptにはびっくりさせられることがある。
判定式にboolean型以外の型の変数だけを入れることができるとはね。。。

if ( var ) {
  // procedure
}
変数の型判定
文字列空文字以外はtrue
数値0かNaN以外はtrue
objectnull以外はtrue
undefinedfalse
nullfalse

Javaだとメソッドでbooleanを戻すようにしているから、こっち方が楽ですね

<JavaScript>JavaScriptの月インデックスはゼロ始まり

ドットインストールでJavaScript入門を連続再生させて聞いていて、気をつけなきゃなと思ったことのメモ

JavaScriptの月インデックスはゼロ始まり

JavaScriptでは、月はゼロから始まります。 次のように、getMonthを使った時は、インデックスに1を足しましょう。

//JS
var date  = new Date();
var month = date.getMonth()+1;

違う例えとして、特定の日付オブジェクト生成時を、ブログ更新中の今の時間にしてみる。
※ 2016/10/22 17:50

var date = new Date(2016, 9, 22, 17, 50, 00);

参照:

先人の知恵に、ひたすら感謝です

ノルマ

SEのための会計の教科書という本を読んでいて、「おっ」と思った、『ノルマ』の語源。

このノルマの語源はロシア語で、決められた時間内に行うべき作業量を意味し、
シベライ抑留者によって日本に伝わったといわれている。

そりゃ、なんとも達成せんとな。。。

<Java>ResultSetからのデータ抽出は、カラム番号ではなくカラム名で!

Javaの小ネタ。実装時にどのメソッドを使うべきか、という低レベルな話です。

ResultSetからのデータ抽出

JavaでデータベースにSQLのSELECT文を流す際、PreparedStatementとResultSetを使います。
ResultSetから値を取り出す際は、引数はカラム番号ではなくカラム名にしましょう。

例えば、ResultSetには、文字列を取り出すメソッドが2つ用意されています。
正確には、オーバーライドされて、カラム番号(int)とカラム名(String)のどちらも引数に取れるということです。

  • String getString(int columnIndex)
  • String getString(String columnLabel)

columnIndex(カラム番号)は、1始まりなので、配列のインデックスと間違えて、ゼロ始まりとしてしまう可能性があります。
また、columnLabel(カラム名)としておけば、可読性も増します。
まとめとして、ResultSetから値を取り出す際は、引数はカラム名を使いましょう。

<Java>コンストラクタの継承はない

Javaの入門書を読み直して、「あー、そうだったね。」という点を書いてみます。

  • メソッドのシグネチャは下記3つ
    1. 戻り値の型
    2. メソッド名
    3. 引数の型
  • 親クラスが持つ、引数の数が違うコンストラクタは、子クラスでは呼び出せない
    ※ メソッドとは違って、引き継がれない(透けて見えることがない) ※ superで呼び出すことはできます。
    ※ (追記)まぁ、コンストラクタ名が違うので当たり前ですよね。。。
  • 親クラスで引数を持つコンストラクタが定義された場合、子クラスで呼び出さないとコンパイルエラーとなる
    ※ 正確にいうと、親クラスに対応するコンストラクタがないと、子クラスのインスタンス生成時にコンパイルエラーになるよって話

継承は、メソッドだけでなく、コンストラクタにも縛りがあり、親子間の共通化が徹底されている(保証されている)ことを再認識しました。

2016年10月3日月曜日

PS/2端子って、プラグアンドプレーに対応してないのな

PCの立ち上げ(キッティング)やPC自作している人には、常識かもしれませんが、
PS/2端子でキーボードやマウスをつなげた場合、PCの再起動が必要なんですね。

つまり、プラグアンドプレー(周辺機器をPCにつなげたら自動認識・設定する機能)に対応していない。
前の会社は、ノートパソコンメインで使っていたので、全然知らなかった。

2016年10月1日土曜日

vagrant upで"Failed to mount folders in Linux guest."

勉強のため、Postgre SQLを玩ぼうと、久々にvagrantを立ち上げたら、virtual machineは立ち上がるものも、マウントに失敗しる模様。

$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Checking if box 'bento/centos-6.7' is up to date...
==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
    default: Adapter 2: hostonly
==> default: Forwarding ports...
    default: 22 => 2222 (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Warning: Connection timeout. Retrying...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
==> default: Configuring and enabling network interfaces...
==> default: Mounting shared folders...
    default: /vagrant => /Users/user/myvagrant/mycentos
Failed to mount folders in Linux guest. This is usually because
the "vboxsf" file system is not available. Please verify that
the guest additions are properly installed in the guest and
can work properly. The command attempted was:

mount -t vboxsf -o uid=`id -u vagrant`,gid=`getent group vagrant | cut -d: -f3` vagrant /vagrant
mount -t vboxsf -o uid=`id -u vagrant`,gid=`id -g vagrant` vagrant /vagrant

The error output from the last command was:

/sbin/mount.vboxsf: mounting failed with the error: No such device

$ 

下記のブログを参考になんとか解決しました。

事象内容

1. guest osとhost osでvirtual boxのvirtual boxのバージョンが違うと、共有ディレクトリがリンクできない。
2. vagnrat vbguest installによりguest osのvirtual boxのバージョンアップを試みたが、カーネルの更新で失敗していた。

対応内容

まずは、2から。
2. guest osにvagrant sshしてyumでカーネルを更新※今回のguest osはcent os 6.7でしたので、yum。
$ sudo yum -y update kernel
念のため、下記も実行しました。
yum -y install kernel-devel kernel-headers dkms gcc gcc-c++
1. guest osを再起動したら直りました。
$ vagrant reload

2016年9月29日木曜日

わかりやすいアジャイル開発の教科書

アジャイル開発ってよく聞くけどなんやねん、ということで本書を手に取ってみました。
アジャイルが出てきた背景として、、過去にソフトウェア工学が発展する中で包括的なドキュメントや計画が重視され、人がおざなりなる傾向があったことを理解できました。

過去に自分が経験したことですが、時間をかけて業務の補助ツールを作成したのですが、「これじゃない」感があり満足した成果が得られないことがありました。こういう「価値がない」状態を二度と発生しないために何ができるのか。

アジャイルの目的

アジャイルの目的は「価値」の最大化です。

価値を定義しなさい、価値を。

ソフトウェアの開発を委託する顧客は、「このソフトウェア/システムがあれば業務効率が上がって収益が上がるはずだ」など、そのソフトウェア/システムに対して費用を払って得られる利益を期待しています。その期待が顧客にとってのソフトウェアの価値になります。

ソフトウェア/システムによって得られる効果・成果のことですね。

「アジャイルソフトウェア開発」とは

ある特定の開発手法を指すものではなく、ソフトウェアの価値を最大限に高めるために、エンジニア、マネージャ、顧客も含めて取り組むべき「考え方」や「姿勢」です。

もちろん、いろいろな手法や手順が本書で紹介されているのですが、それはアジャイルソフトウェア開発を実現する手段であって、アジャイルソフトウェア開発というのはあくまで「考え方」や「姿勢」ということみたいです。

その他、気になった部分だけ列挙します。

  • こたつモデル
  • プロジェクト内に、時間の長さが一定のタイムボックスというもので細分化する
  • タイムボックスの長さは、プロジェクトの長さを10-12ぐらいで分けるのが最適らしい
  • タイムボックスの長さが固定なのは、作業効率(ベロシティ)を把握するため
  • タイムボックスごとに「ふりかえり」を行う
  • プロジェクトを、ストーリーとして捉える
  • 最後のタイムボックス終了までにストーリーを完結させる。
  • YAGNI ※特段アジャイルに限ったことではないと思いますが
  • プロジェクトだって、ソフトウェアと同じく、INPUT -> 処理 -> OUTPUT という流れになっている
  • ソフトウェアカンバン
  • やるべき項目を「タスク」として細分化するが、その細分化の大きさは「半日から2日」
  • タスクを「Done」にする条件(Doneの定義)をチーム内で決める
  • Redmineによるチケット駆動開発(TiDD)
  • テスト駆動開発(TDD)では「予定通り失敗する感覚」が大事

実践が肝ですが、それが課題です。

2016年9月27日火曜日

スペアザいいね - special others

2016/10/01 更新

自転車屋さんでかかっていたけど、スペアザ(special others)初めて聞いた。
いやー、かっこいいですね。カラダ動かしたくなるようなテンポがいい。
調べてみるとケッコー息の長いバンドでした。すでにファンの方からしてみれば「今頃かよ」って感じでしょうか。


キラキラした感じの曲たち

SPECIAL OTHERS & Kj (from Dragon Ash) - Sailin' 【MUSIC VIDEO】

SPECIAL OTHERS - AIMS 【MUSIC VIDEO SHORT.】

SPECIAL OTHERS - Surdo 【MUSIC VIDEO SHORT.】


こういう楽しい楽しい感じのもある
youtubeになかったのでニコ動ですが

ドローン検定3級を受験してきました!

タイトルの通り、一昨日(2016/09/25 Sun)にドローン検定3級を受験してきました!

同じ日に1級を受験していた知り合い曰く、開始10分前ぐらいにテキスト読むぐらいで余裕だよということでしたが、自分はドローンと今まで無縁だったので2回通読して本番に臨みました。試験自体が簡単であったので、自己採点は90点で合格していると思います。

ドローン検定って何?

正式名称は、「無人航空従事者試験」らしいです。
ドローン検定協会 株式会社が実施している「民間の検定」です。
一般財団法人が後援しているものも、お国は関係ないものと思われます。

似ているものとして、一般財団法人 JAREXが実施している、「ドローン技能検定」というものがあります。
技能とついているだけあり、こちらは飛ばす技術を実技で試験されます。
一方、今回私が受験した、ドローン検定協会が実施している「ドローン検定」はペーパー試験オンリーです。 詳しくはこちらのリンクをご参照ください。(2016/09/27時点)
ドローン検定協会 ドローン検定
一般財団法人 JAREX ドローン技能検定

どこ、いつ、いくらで受けられるの?

Webページを見たところ、主要な都道府県で実施しているみたいです。
今回、私は東京・新橋で受験しました。貸会議室を会場でした。
今年は、2ヶ月ごとに、年間で6回開催するみたいです。今年のラストは11月です。

本記事の書いている時点の受験料は下記をご参照願います。

受験資格 受験料
1級 ドローン検定協会主催 ドローン検定2級取得者 18,000円
2級 ドローン検定協会主催 ドローン検定3級取得者 12,000円
3級 どなたでも受験可能です 5,500円
4級 どなたでも受験可能です 3,000円

ドローン検定受からないとドローンを飛ばしきゃいけないの?

No.
航空法に則ってドローンを飛行させれば、ドローンの操作に資格・認定は不要みたいです。
ただ、夜間に飛行させる場合や目視できない(しない)飛行、人口密集地での飛行については、承認申請する必要があります。
その申請の際に、記載できて客観的に知識の保有を証明することができます。

ドローン検定難しい?

簡単です。こんな簡単な問題でいいの?!ってくらい簡単です。
問題数50問ですが、すべて4肢1択。つまり、問題に対する説明文が4つあって、その中であっているか・間違っているものを1つ選ぶというものです。
問題のうち、だいたい40問はテキストに記載の問題そのままでした。2問ぐらいはテキストにない語句の説明だったと思います。
残りは、テキストの問題の若干のアレンジです。

3級については、検定を通して、知識を浸透させるとともに、もっと認知度を高めたいと考えているのかな、って私はうがっています。
対して、1級・2級は受験料高すぎじゃないですか。。。

2016年9月25日日曜日

「行う」と「行なう」はどっちも正しい

本を読んでて思わずググった。
「あれ、"行う"じゃなくて"行う"だよな?」と。

ところがびっくり、どっちも正しいらしい。へぇー。
まぁ、言葉なんて通じりゃいいすけどね

最初に結論から述べますと、どちらも使い方としては誤りではありません。
以前は「行なう」が本則だったものの、1973(昭和48)年、国語審議会の方針が変わったことにより、「行う」が標準となる内閣訓示が出されました。

これにより、現在では公的機関やビジネスシーンでも「行う」を使うのが一般的ですし、教科書でも「行う」が使われています。
ただし、「行なう」の表記も誤りではないため、容認されているようです。

とはいえ、「行う」を使ったほうが無難といえるでしょう。

引用元:「行う」と「行なう」の違いは?送り仮名はどっち?正しい使い分けを学ぼう!

"行う"で習ってたから違和感を覚えたわけだ。。。

<Java>変数のデフォルト値

クラス変数 => 初期化しないと参照先がない
     ※この状態で変数を呼び出すと、コンパイルエラーとなります。

メンバ変数 => インスタンス化した時点で、デフォルト値が入る
     boolean型以外の基本型 = ゼロ
     boolean = false
     オブジェクト参照型 = null

インスタンスかどうかで変わるのが、紛らわしいところです。

java.lang.ArrayIndexOutOfBoundsException

Javaの基本的なエラーの一つ
配列のインデックスが、配列の範囲外であった時に発生する例外です。
面白いことに、java.langパッケージなんですね。

エラーメッセージとして、不正なインデックス値が明示されます。
下記は、コード例です。


 8: public static void main(String[] args) {
 9:  int a = Integer.parseInt(args[0]);
10:  int b = Integer.parseInt(args[-1]);
11:  int c = a + b;
12:  System.out.println(c);
13: }

エラーメッセージは下記の通りです。


Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
 at example.Example1.main(Example1.java:10)

Eclipseでのコンパイルエラーの表示箇所

EclipseでJavaをコーディングする上での基本ですが、コンパイルエラーの詳細は下記のように表示されます。

どのアプリケーションの、
  どのクラスで、
    どのスレッドで、どんなエラーが
      どのメソッドで発生したか、
を示す構造です。

上記の例ですと、intがた変数にdouble型の値を代入しようとしたことを示します。
下記がコードです。


public class Example1 {

 /**
  * @param args
  */
 public static void main(String[] args) {
  double d = 12.3;
  
  int i = d;
  System.out.println(d);
  System.out.println(i);
 }

}

MacOS上のEclipseで"MacRoman文字エンコードを使用してマップすることはできません"

StackOverFlow、お世話になっています。

MacOSで日本語入力したところ、下記のエラーが出ました。

保管を完了できませんでした。 理由: 一部の文字は"MacRoman"文字エンコードを使用してマップすることはできません。 エンコードを変更するか、"MacRoman"文字エンコードによってサポートされていない文字を除去してください。

下記の設定で問題なく実行できました。
Preference => General => Workspace
- Text file encoding = Other(UTF-8)
- New text file line delimiter = Other(Unix)

6年の前の記事 ですが、助かりました。

一知半解

いっちはんかい

少ししか分かっておらず、十分に理解していないこと。生半可な知識や理解しかないこと。生かじり。一つの事を知っているが半分しか理解していない意。
引用:goo辞書

ドローン通信用へ5.7/2.4 GHz帯解放

月刊テレコミュニケーション Sep.2016で、ドローン通信用へ5.7/2.4 GHz帯解放 の記事が載っていたので、購入してみました。


技術&トレンド
"目視外飛行"で広がる産業利用の可能性
ドローンに映像対応の新周波数帯

という記事になります。

新周波数によるメリットは5kmの長距離映像伝送が可能になること。現行の無線LANでは、高性能な機種でも1 - 2kmにとどまるそうです。無線LANの200mW(10mW/MHz)の5倍の1Wで出力できるようになったため伝送距離が伸びたみたいです。

また、ポイントとしては、これらの周波数の使用については業務用途が想定されていて、勝手に使えるわけではないこと。3級陸上特殊無線技士以上の資格者を配置し、無線局免許を取得する必要性があるそうです。

ホビーとしてやるぶんには関係がないですね(^^;

毀誉褒貶

# テーマ
毀誉褒貶

# 読み方
きよほうへん

# 使用例
- 毀誉褒貶相半ばする
- 毀誉褒貶入れ乱れる
どちらの言葉も、高く評価する人もいればけなす人もいるという意味です。

eclipse4.6 pluginの設定ではまる(MacOS 10.11.5)

下記の環境ではダウンロードしたプラグイン(.jar)は、/Users/<user-name>/eclipse/jee-neon/Eclipse.app/Contents/Eclipse/plugins/ に格納しましょう。

・eclipse4.6
・MacOS 10.11.5

頭のいい人たちが考えたすごい!「仕組み」

NHK ITホワイトボックス 世界一やさしいネット力養成講座 パソコンとケータイ 頭のいい人たちが考えたすごい!「仕組み」 (NHK ITホワイトボックス―世界一やさしいネット力養成講座)

読みやすい構成とコンパクトな内容。

2011年発行の本書は、その時点でのITに関するキーワードの概要と背景を分かりやすく説明しています。イラストも適宜入っていますし、解説が必要と思われる用語は、節の終わりに解説されていました。

ITの実用例として面白いなと思ったのが、「洗濯物が乾いたことを知らせてくれるシステム」です。

これはハンガーにセンサーと無線通信機能を組み込んだもので、センサーはハンガーに掛けられた洗濯物の湿気を感知します。洗濯物が乾いて湿気がなくなると電気を通さなくなるので、それを合図としてセンサーが無線通信機能でパソコンに情報を送信。それを受けてパソコンは、ユーザーの携帯電話にメールで「洗濯物が乾いた」という連絡を入れるのです。
日経ソフトウェアあたりで、RasberryPiを使って、観葉植物に水をやる装置みたいなものを見たことがあったので、洗濯物センサーもイメージしやすかったです。乾いたことを知らせるからさらに、雨が降って再び濡れたというのも感知できそうですね。

さらに3つほど知らなかったことを記載しておきます。

1つは、医療機器向けの通信規格コンティニアです。 昨今デジタル機器で歩数・血圧・体重などを管理する方が増えているかと思いますが、それらの項目の測定機器の無線通信に関する標準規格がコンティニアだそうです。メーカー横断的な規格を作り、機器の普及を促す目的です。

2つ目は、Androidのサンドボックスモデル。これは、セキュリティ対策の一つで、アプリに割り当てる領域を区切り、もし1つのアプリ領域がウィルスに感染したとしても、他の領域へのアクセスを防ぎ、他のアプリのデータやスマホの重要な基本データの流出を阻止するというもの。

3つ目は、ソーシャルゲームのピーク時間。 モバイルソーシャルゲームにおていは、1日に3回のピークがある。 出勤・登校の8時ごろ、昼休みの12時ごろ、帰宅時間の16 - 23時ごろです。 言われてみると当たり前ですが、サービス提供・運営側は、このことを意識する必要があります。

* * * 刊行から約5年経っているので、今のホットワードではないかもしれませんが、自分はITに詳しくないと思っている方にはいいかもしれません。