のいじーメモ

勉強したことを忘れないうちにメモしていくためのブログ

PDOの説明

自分なりにPDOについて勉強したのでここにまとめます。

作成したサンプルコード

 

<?php
$db = new PDO('mysql:host=localhost;dbname=db_name;charset=utf8','user','password');
$db->setAttribute ( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

$loginid = "var";
$sql = "SELECT * from users WHERE loginid= :loginid ";

$statement = $db->prepare($sql);

$statement->bindValue(':loginid',$loginid,PDO::PARAM_STR);
$statement->execute();

while($user = $statement->fetch(PDO::FETCH_ASSOC)){

echo $user["loginid"] . "<br>";
}


PDO (PHP Data Objects)

データアクセス抽象化レイヤーと言われ、アプリケーションとDBMS(データベース管理システム)の間に入ってDBMSの違いを意識せずにアプリケーションを作成するもの。
データベースの違いを意識しないで同じ書き方で使える。

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

エミュレーションがONの場合のみ, ; 区切りで複数のSQL文を1つのクエリで実行することができる.
エミュレートの設定がONだと動的プレースホルダになり、OFFだと静的プレースホルダになる。


ユーザー入力を受け取ってSQL文を動的に生成する場合は プリペアドステートメントプレースホルダ を使わなければならない.

プレースホルダ:
直訳すると「場所取り」.何かユーザ入力を当てはめる場所としてあらかじめ確保しておくもの.
プリペアドステートメント:
直訳すると「予約文」.文を予約したもの.通常,「予約文」は「場所取り」を使うために作られる.もし「場所取り」が無ければ普通に PDO::query などで実行するだけで十分なためである.
プレースホルダには2種類あり,疑問符プレースホルダ を使う方法と, 名前付きプレースホルダ を使う方法がある.もしこれらが混ざってしまうと

SQLSTATE[HY093]: Invalid parameter number: mixed named and positional parameters

が発生するので、どちらか一方のみを選択すること.

動的プレースホルダと静的プレースホルダの違い

IPAの出している「安全なSQLの呼び出し方」では、
静的プレースホルダは、SQL文をデータベースエンジン側にあらかじめ送信して、実行前にSQL文の構文解析などを準備しておく方式です。 SQL 実行の段階で、実際のパラメータの値をデータ
ベースエンジン側に送信し、データベースエンジン側がバインド処理します。
動的プレースホルダは、パラメータのバインド処理をデータベースエンジン側で行うのではなく、アプリケーション側のライブラリ内で実行する方式です。
と説明されている。

参考URL
IPA 安全なSQLの呼び出し方
https://www.ipa.go.jp/files/000017320.pdf
qiita PDOの静的プレースホルダと動的プレースホルダの違いを確認する
http://qiita.com/7968/items/7ddd59b94eb5a4fb6eaf

バインド機構

SQLインジェクションを防ぐために、プログラムのソースコードSQL文の雛(ひな)型の中に変数の場所を示す記号(プレースホルダと呼ばれる)を置いた後、実際の値を割り当てる仕組み。
入力値中の特殊記号も単なる値として渡されるためエスケープ処理なしで安全にSQL文を発行することが可能となる。
データベースシステムやプログラム言語によっては、この機構が用意されているものもありSQLインジェクション対策として有用である。

 

bindValue:値をバインドする 実行する前に値をバインドする
bindParam:変数をバインドする 実際に値を評価するのはexecute()の時。

基本的にbindValue推奨
理由:実行後にバインドした変数が文字列型にされる仕様もあるから
参考URL
http://qiita.com/_dozen_/items/e3c00a0a581378a4cc70

ということで値をバインドする。

$statement->bindValue(':loginid',$loginid,PDO::PARAM_STR);

 参考URL
qiita bindValueとbindParamの違い
http://piyopiyocs.blog115.fc2.com/blog-entry-656.html
qiita PHPでデータベースに接続するときのまとめ
http://qiita.com/mpyw/items/b00b72c5c95aac573b71

Docker よく使うコマンド集

Dockerイメージリストの確認

$ docker images

Dockerイメージからコンテナ作成、起動

$ docker run -i -t [REPOSITRY名:TAG名] /bin/bash

Dockerコンテナからイメージを作成する

$ docker commit [コンテナid] [REPOSITRY名:TAG名]

Dockerコンテナの確認(停止中コンテナも表示する場合は -a オプションをつける)

$ docker ps -a

停止中のDockerコンテナを稼働させる

$ docker start [コンテナid]

稼働中のDockerコンテナを停止させる

$ docker stop [コンテナid]

 

Dockerコンテナ削除

$ docker rm [コンテナid]

Dockerイメージ削除

$ docker rmi [イメージid]

・便利なdockerコマンド

稼働しているdockerコンテナすべて停止

$docker stop `docker ps -q`

dockerコンテナすべて削除
$docker rm `docker ps -a -q`

コンテナからexitするときにコンテナ削除(使い捨て)
$docker run -ti --rm [イメージID]


centosでsystemctl start [サービス名]とするとエラーがでる場合
$ docker run --privileged -d --name http centos /sbin/init

コンテナ内で作業する

$ docker exec -it http bash

サービスを立ち上げてコンテナ起動

centos7の場合
$ docker run --privileged -d -p 80:80 --name httpd centos:centos7 /sbin/init


centos6の場合
$ docker run -p 8080:80 -d cent6_apache /usr/sbin/apachectl -DFOREGROUND


docker イメージの保管場所

まずdockerのimage ID の確認
$ cat /var/lib/docker/repositories-devicemapper

表示されたJSONJSON Lintなどにかけて読みやすくするなどして探したいイメージファイルのIDを探す

$ ls /var/lib/docker/graph/[image ID]

 

作成したコンテナを別PCで動作させる方法

Dockerコンテナをファイル出力する


$ docker export [コンテナid] > [出力ファイル名]
出力したコンテナファイルを開発メンバーに渡して、メンバーは出力ファイルをインポートコマンドで叩けば、構築済みのDockerイメージを得ることができる為、docker runすることで同一環境を得ることが可能

cat [インポートファイル] | docker import - [REPOSITRY名:TAG]

docker-compose

バックグラウンドで立ち上げる

$ docker-compose up -d

Docker exec的なやつ
docker exec -it $(docker-compose ps -q httpd) bash

Docker-composeのimageをdownついでに削除
docker-compose down --rmi all

ICMPで遊ぶ

クリスマスなのでリア充っぽい機能を作成しようと思います。 ICMPリクエストのペイロードに "I love you"という文字列をのっけて送信すると
"I love you too."をペイロードに乗っけて返信してくれるサーバーを作りましょう。
iptablesでecho-requestのICMPパケットをNFQUEUEターゲットでキューに入れ、それをpythonで処理します。

from scapy.all import *
from netfilterqueue import NetfilterQueue

def icmp_fake(pkt):
    ip = IP()
    icmp = ICMP()
    ip.src = pkt[IP].dst
    ip.dst = pkt[IP].src
    icmp.type = 0
    icmp.code = 0
    icmp.id = pkt[ICMP].id
    icmp.seq = pkt[ICMP].seq
    print (ip.src + "=>" + ip.dst)
    print(pkt[ICMP].load)
    if pkt[ICMP].load == "I love you.":
        send(ip/icmp/"I love you too.")
    else:
        data = pkt[ICMP].load
        send(ip/icmp/data)

def is_icmp(pkt):
    packet = IP(pkt.get_payload())
    proto = packet.proto
    if proto == 0x01:
        if packet[ICMP].type == 8:
            icmp_fake(packet)
            
            
nfqueue = NetfilterQueue()
nfqueue.bind(1, is_icmp)
try:
    nfqueue.run()
except KeyboardInterrupt:
    print('')

nfqueue.unbind()

iptablesの設定はこんな感じ

iptables -A INPUT -p icmp --icmp-type echo-request -j NFQUEUE --queue-num 1

クライアントからICMPパケット送信

 $sudo scapy
 >>>sr1(IP(dst="192.168.11.52")/ICMP()/"I love you.")
    Begin emission:
..Finished to send 1 packets.
...................................................................................*
Received 86 packets, got 1 answers, remaining 0 packets
<IP  version=4L ihl=5L tos=0x0 len=43 id=1 flags= frag=0L ttl=64 proto=icmp chksum=0x5a27 src=192.168.11.52 dst=192.168.11.50 options=[] |<ICMP  type=echo-reply code=0 chksum=0x8638 id=0x0 seq=0x0 |<Raw  load='I love you too.' |<Padding  load='\x00\x00\x00' |>>>>

ちゃんと愛されていますね。まぁ誰にでも"I love you too."と送るようなビッチですが居ないよりはマシでしょう。

lambda式で関数を定義しよう

私はよくもの忘れをするサルなのでここに備忘録として書き記していこうと思います。

 

lambda式・・・無名関数とも呼ばれる。リストや辞書などの要素の処理につかわれる。

例:

    lambda 引数1, 引数2 ....: 処理

まずは最初にlambda式を使わないで書いてみましょう。

    
    def small(num1, num2):
        return num2 if num1 > num2 else num1
    
    print(small(5, 3))
    print(small(7, 9))

実行結果

    3
    7

次はこれをlambda式で書いてみましょう。

    small = lambda num1, num2 : num2 if num1 > num2 else num1

    print(small(5, 3))
    print(small(7, 9))

実行結果

    3
    7

同じ結果が得られます。

このようにlambda式は小規模の関数を手軽に書くのに適しているわけですね。 是非活用していきたいです。

pythonでTwitterに投稿

今回はtwitter APIを取得してpythonでtweetをするプログラムを書きたいと思います。

twitter APIへアクセスするにはOAuth認証が必要です。

  • OAuth 認証に必要な物
    • Consumer key
    • Consumer secret
    • Access token
    • Access token secret

この4つの認証keyが必要になります。

認証keyの取得についてはこちらのページを参照してください。

website-planner.com

それではやっていきましょう。

 

from requests_oauthlib import OAuth1Session
import json
import random

CK = '*******************' # Consumer Key
CS = '*******************' # Consumer Secret
AT = '*******************' # Access Token
TS = '*******************' # Access Token Secert

url = "https://api.twitter.com/1.1/statuses/update.json"

params = {"status": "Hello,world!"}

twitter = OAuth1Session(CK, CS, AT, TS)
req = twitter.post(url,params = params)

if req.status_code == 200:
  print("OK")
else:
  print("Error: %d" % req.status_code)

 

 

 

PHPのメモ

PHPのメモ

PHPの勉強を最近始めたので備忘録としてここに記していこうと思います。

count($array) 配列の要素数を抽出
rand(下限値,上限値) 下限値~上限値までの整数をランダムに返す

wiresharkを使うときの便利なフィルタ

 

ディスプレイフィルタの構文

ディスプレイフィルタの構文説明

ip.addr == 10.0.0.1

送信元、もしくは送信先が10.0.0.1であるパケットを表示

ip.addr==10.0.0.1 && ip.addr==10.0.0.2

10.0.0.1と10.0.0.2間の通信を表示

http or dns

HTTP、もしくはDNSを表示

tcp.port==4000

ポートが4000の物を表示

tcp.flags.reset==1

TCPのリセットを表示

http.request

HTTP GETを表示

tcp contains traffic

TCPパケットに’traffic’という単語を含んでいる物を表示。ユーザーIDといった特定の文字列を含んでいるパケットを調べる際に便利。

!(arp or icmp or dns)

ARPやICMPやDNSでないプロトコルを表示。 調べたいパケットに集中することができる。

udp contains 33:27:58

“0x33 0x27 0x58”を含むUDPを表示

tcp.analysis.retransmission

TCPのRetransmission (= 再送) を表示。 アプリのパフォーマンス問題、パケットロス時のトラブルシューティングに便利。