ねっとぱんだ-プログラミング勉強ブログ-

Webデザイン、プログラミングの勉強ブログ。

【php】PDO::setAttribute

PDO::setAttribute

参考
http://php.net/manual/ja/pdo.setattribute.php
  • 属性を設定する
  • データベースハンドルの属性を設定
  • いくつかのドライバでは、 ドライバ固有の属性を使用することが可能

説明の詳細(データベースハンドル、ドライバ?)

参考
https://msdn.microsoft.com/ja-jp/library/windows/hardware/ff554678(v=vs.85).aspx

データベースハンドル

  • handle = 操作するもの
  • プログラムは、メモリ上に配置される
  • メモリ上に配置されたプログラムに対して、その内容に従ってCPU が処理を実行
  • 例)ボタンやテキストボックス(文字列の入出力をする部位)等も、メモリ上に配置される
    • ボタンのメモリ配置上の先頭アドレスを「ボタンのハンドル」と言う
    • ボタンのハンドルを取得するプログラム = ボタンの表示文字を他の文字に替えたり、ボタンの大きさを替えられる
    • テキストボックスのハンドルを取得すれば、そのテキストボックスにユーザーが書き込んだ文字列を取得することが可能

ドライバ

  • driver 運転手、操縦者、駆動装置、推進力
  • ドライバーとはオペレーティング システムとデバイスの間で相互のやり取りを可能にするソフトウェア コンポーネント
  • ドライバ回路 電子回路で、対象に電力を供給して動かしたり、遮断して止めたりする機能を持った回路
  • デバイスドライバ コンピュータ内部に装着した装置や、外部に接続した機器を制御・操作するための専用のソフトウェア
  • 例)アプリケーションでデバイスからデータを読み取る必要がある場合
    • アプリケーションはオペレーティング システムで実装された関数を呼び出す
    • オペレーティング システムはドライバーで実装された関数を呼び出す
    • バイスの設計と製造をした会社が作ったドライバーであれば、デバイス ハードウェアとやり取りする方法を認識してデータを取得
    • データはオペレーティング システムに返され、さらにアプリケーションへと返される

具体的な記述

$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

PDO::ATTR_CASE

PDO::CASE_LOWER
強制的にカラム名を小文字にする
PDO::CASE_NATURAL
データベースドライバによって返されるカラム名をそのままにする
PDO::CASE_UPPER
強制的にカラム名を大文字にする
PDO::ATTR_ERRMODE

  • エラーレポート

PDO::ERRMODE_SILENT
エラーコードのみ設定する
PDO::ERRMODE_WARNING
E_WARNING を発生させる
PDO::ERRMODE_EXCEPTION
例外 を投げる

PDO::ATTR_ORACLE_NULLS

  • Oracle だけでなく、全てのドライバで利用可能
  • NULL と空文字列の変換

PDO::NULL_NATURAL
変換しない
PDO::NULL_EMPTY_STRING
空文字は NULL に変換される
PDO::NULL_TO_STRING
NULL は空文字に変換される

返り値 ¶

成功した場合に TRUE を、失敗した場合に FALSE を返します。

その他

http://php.net/manual/ja/pdo.setattribute.php

  • PDO::ATTR_STATEMENT_CLASS
  • PDO::ATTR_TIMEOUT
  • PDO::ATTR_AUTOCOMMIT
  • PDO::ATTR_EMULATE_PREPARES
  • PDO::MYSQL_ATTR_USE_BUFFERED_QUERY
  • PDO::ATTR_DEFAULT_FETCH_MODE

【sql】FOREIGN KEY 制約 外部キー

FOREIGN KEY 制約 外部キー

参考
https://www.dbonline.jp/mysql/table/index11.html
http://blog.hori-uchi.com/2009/11/mysql.html

指定したカラムに格納する値を、他のテーブルに格納されている値に限定する。

ALTER TABLE テーブル名 ADD FOREIGN KEY (制約を張りたいカラム) REFERENCES 張りたいテーブル(張りたいカラム);

【php】config.php 複数ファイルで使う関数や変数をまとめる

ファイルをまとめる

dotinstallなどのコードで、データベースに接続する時など複数ファイルで使う関数をまとめていたのでメモしておきます。

コード

各ファイルで読み込む

require_once(__DIR__.'/config.php');

config.php

<?php
//エラーを表示させる
ini_set('display_errors',1);

//PDOに必要な値
define('DSN','mysql:host=ホスト;dbname=データベース名;charset=utf8');
define('DB_USERNAME','ユーザー名');
define('DB_PASSWORD','パスワード');

//特殊文字をエスケープしてその値を返す関数
function h($s){
  return htmlspecialchars($s,ENT_QUOTES,'UTF-8');
}

【java】コレクション・フレームワークとArrayList(再)

コレクションフレームワークに含まれるクラス/インターフェース

参考
https://rat.cis.k.hosei.ac.jp/article/java/lesson/collection1.html

java.util.Collection

List
順序付きリストのインターフェース
ArrayList
配列を用いたjava.util.Listの実装
LinkedList
リンクリストを用いたjava.util.Listの実装
Set
重複を許さない集合のインターフェース
HashSet
ハッシュを用いたjava.util.Setの実装
TreeSet
二分探索木を用いたjava.util.Setの実装

Map

  • キーと値のペアを表現
Map
キーと値のペアを表す構造のインターフェース
HashMap
キーの検索にハッシュを用いたjava.util.Mapの実装
TreeMap
キーの検索に二分探索木を用いたjava.util.Mapの実装

ArrayListとLinkedListの違い

  • ArrayList
    • 要素を配列で保持している
      • 配列がメモリ上でインデックス化されている
      • インデックスの修正、コピーに対するコストが要素数に比例して大きくなる
      • 要素がメモリ上のインデックスに保管されているため、n番目の要素へのアクセスが早い

「データベースからデータを大量に読み込み、以後それを順に参照しつつ複雑な計算を行うような場合」に適している

  • LinkedList
    • 要素を数珠つなぎに保持している
      • 前後の要素に対するリファレンスを保持している
        • 要素の追加、削除はリファレンスの変更のみでOKのため、コストが一定
        • ある要素が何番目かが分からないため、n番目の要素に対して1から順にたどる必要がある

「プログラム中で発生するデータの入れ物として使われ、時折データベースへ書き出してデータの永続化が図られるような用途」に適している

宣言
参考
http://qiita.com/Mura-Mi/items/e52c28ab7cb5db140d53

Listで宣言する場合とArrayList(or LinkedList)で宣言する場合がある。

ArrayListのメソッドはArrayListで宣言した場合でだけ使える

import java.util.List;
import java.util.ArrayList;
import java.util.LinkedList;

public class Box{
	private ArrayList<String> fruits;
	
    //初期値としてfruitsをArrayListとする
	void Box(String name){
		this.fruits = new ArrayList<>();
	}
	
	//引数に渡されたArrayListをfruitsに入れる
	void refleshBox(ArrayList<String> newFruits){
		this.fruits = newFruits;
	}
	
	//保持しているfruitsの値を返す(getter)
	ArrayList<String> getAllFruits(){
		return this.fruits;
	}
	
	public static void main(String args[]){
		Box A = new Box();
		
		//新しいLinkedyListを作る
		LinkedList<String> newFruits = new LinkedList();
		newFruits.add("apple");
		newFruits.add("banana");
		newFruits.add("melon");

	}
}

上記ではLinkedListをrefreshBoxメソッドに渡そうとした時、引数がArrayListである為、格納できない。

		//引数がArrayListの為LinkedListを受け取れない
		A.refleshBox(newFruits);
		//LinkedListで宣言すると、ArrayListは受け取れない
		LinkedList<String> fruits = A.getAllFruits();

Listで宣言する場合

import java.util.List;
import java.util.ArrayList;
import java.util.LinkedList;

public class Box{
	private List<String> fruits;
	
	//初期値としてfruitsをArrayListとする
	void Box(){
		this.fruits = new ArrayList<>();
	}
	
	//List型ならどれでも格納できる
	void refleshBox(List<String> newFruits){
		this.fruits = newFruits;
	}
	
	//保持しているfruitsの値を返す(getter)
	List<String> getAllFruits(){
		return this.fruits;
	}
	
	public static void main(String args[]){
		Box A = new Box();
		
		//新しいLinkedListを作る
		LinkedList<String> newFruits = new LinkedList<>();
		newFruits.add("apple");
		newFruits.add("banana");
		newFruits.add("melon");

	}
}

上記では引数もListで宣言している為、LinkedListをrefleshBoxメソッドの引数に渡しても受け取れる

		//LinkedListをfruitsに格納できる
		A.refleshBox(newFruits);
		//List型なら全て格納できる
		List<String> fruits = A.getAllFruits();

【java】Math、Random

Mathクラス、Randomクラス

import java.util.Random;

public class Main{
	public static void main(String args[]){
		
		double d = 43.64;
		//繰り上げ
		System.out.println(Math.ceil(d));
		//切り捨て
		System.out.println(Math.floor(d));
		//四捨五入
		System.out.println(Math.round(d));
		//円周率
		System.out.println(Math.PI);
		
		//Mathクラスのrandom
		System.out.println(Math.random());
		//こちらの方が高速で精度がいい
		Random r = new Random();
		//0以上1未満
		System.out.println(r.nextDouble());
		//0から100未満の整数
		System.out.println(r.nextInt(100));
		//ランダムなtrue,false
		System.out.println(r.nextBoolean());
	}
}

【java】Stringの比較、printf

文字列の比較

  • String型は参照型だが基本型(プリミティブ型)と同じように振る舞う
  • 同じ文字列を格納した場合、new演算子を使わなければ同じメモリ領域を参照する
public static void main(String args[]){
		
		String s = "abcdefg";
		//長さ
		System.out.println(s.length());
		//インデックス2から4の前の値まで
		System.out.println(s.substring(2,4));
		//abをABに
		System.out.println(s.replaceAll("ab","AB"));
		
		//同じ文字列の場合、参照型でも同じメモリ領域を参照する
		String s1 = "ab";
		String s2 = "ab";
		
		if(s1.equals(s2)){
			System.out.println("s1 = s2");
		}
		
		//参照型はメモリの格納先の比較
		//しかしプリミティブ型と同じように振る舞う
		if(s1 == s2){
			System.out.println("s1 == s2");
		}
		
		//new演算子で新たにオブジェクトを作ると
		//同じ値でも参照先がかわる
		String s3 = new String ("ab");
		String s4 = new String ("ab");
		
		//参照先が違うのでs3とs4は等しくない
		if(s3 == s4){
			System.out.println("s3 == s4");
		}else{
			System.out.println("s3 != s4");
		}
	}

printf

参考
http://www.ne.jp/asahi/hishidama/home/tech/java/formatter.html
  • 自分の好きな書式で文字列を書き出せる
% 指定を開始、%%で%を出力
%d 10進数の整数を出力
%o 8進数の整数を出力
%x 16進数の整数を出力
%f 浮動小数点数を出力
%c 文字を出力
%s 文字列を出力
%-10s 左詰で10文字の範囲内に出力
デフォルトは右詰
%05sd 5文字の範囲で出力し、空白は0で埋める
数値型のみ
%#o 代替フォームで出力
8進数は頭に0、16進数は頭に0x
%5.4d 整数部5、少数部4文字で表示
%5.4s 5文字のスペースで文字数が4文字
%tY", new Date() 日付(年)

↓その他日付など
http://www.ne.jp/asahi/hishidama/home/tech/java/formatter.html

String.format()
()内に記述すれば文字列として書き出し
	public static void main(String args[]){
		
		int score = 50;
		double height = 165.8;
		String name = "suzuki";
		
		System.out.printf(
			"name: %s, score: %d, height: %f\n", name, score, height
		);
		System.out.printf(
			"name: %-10s, score: %10d, height: %5.2f\n", name, score, height
		);
		
		String s = String.format(
			"name: %10s, score: %-10d, height: %5.2f\n", name, score, height
		);
		System.out.println(s);
	}

【java】コードブレーカーの作成(CUI編)

制作概要

目的

  • javaGUIのコードブレーカーを制作
  • 入出力、GUIの理解

コードブレーカーのルール

参考
http://rulelicca.seesaa.net/article/379848348.html
  • 3つの用意された数字を当てるゲーム
  • 3つ数字を宣言して、答えにある数字と同じ数字がどこかに入っていれば「Blow」
  • 3つの宣言した数字の中で位も数値もあっている部分があれば「Hit」
  • 「Blow」と「Hit」の数から予測して3桁の数字を当てて行く。

CUIでの制作

Math.random()
0以上1未満の乱数
NumberFormatException
文字列を数値にしようとして、文字列が正しくないと起因時に発生する例外
IOException
入出力のエラー

分かりやすいように最初に答えが表示されるようにしています。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class CodeBreaker {

	public static void main(String[] args){
		/*変数の初期化*/
		  //タイトル
		  String title = "***CodeBreaker***";
		  //ルール
		  String rule = "3つの数字を当てよう!\n"
				  +"1から6の数字が用意されます。\n"
				  +"3つの中に同じ数字はありません。\n"
				  +"入力した数字の、"
				  + "位と数字が当たっていれば \"Hit\" \n"
				  + "数字だけ当たっていれば\"Blow\"\n"
				  + "全て\"Hit\" なら終了です。";
		  //3つの数字が入る配列(答えと入力用)
		  int[] answer = new int[3];
		  int[] input = new int[3];
		  //Hit,Blow,入力した回数を入れる変数
		  int hit = 0,blow = 0,count = 0;
		  
		  //キー入力を受け取る
		  BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		  //タイトル、ルールの表示
		  System.out.println(title);
		  System.out.println(rule);
		  
		  //答えの生成
		  //answerの長さ分ループ
		  for(int i = 0; i < answer.length; i++){
			  boolean flag = false;
			  //1~6までの整数を生成
			  //(intでキャストした場合、整数部だけ取り出される)
			  //answerにランダムな整数が挿入
			  answer[i] = (int)(Math.random()*6 +1);
			  do{
				  flag = false;
				  //j(i-1)の値が0以下になるまで(iの値が1以上の時)ループ
				  //つまり最初のforループが2回目になってから
				  for(int j = i -1; j >= 0; j--){
					  //answerの配列の現在の値(i)と前の値(j)を比較
					  if(answer[i] == answer[j]){
						//配列の現在と前の値が同じなら
					  	flag = true;
					  	//配列の現在の値を入れ直す
					    answer[i] = (int)(Math.random()*6 + 1);
					  }
				  }
			  //flagがtrueの間(現在の配列が入れ直しになっている間)
			  }while(flag == true);
		  }
		  //answerの中身を確認
		  String A = "";
		  for(int key : answer){
			  A += String.valueOf(key);
		  }
		   System.out.println("(答え = " + A + ")");
		  
		  //無限ループ
		  while(true){
			  count++;
			  System.out.println("***"+count+"回目***");
			  //インプット
			  //answerの長さ分ループ
			  for(int i = 0; i < answer.length; i++){
				  System.out.println((i + 1)+"個目");
				  try{
					  //input[i]が数値かどうか
					  input[i] = Integer.parseInt(br.readLine());
				  //文字列を数値に変換した時のエラーをキャッチ
				  }catch(NumberFormatException e){
					  System.err.println("数値を入力してください");
					  i--;
				  //入力時のエラーをキャッチ
				  }catch (IOException e){
					  System.err.println("もう一度入力してください");
					  i--;
				  }
			  }
			  //答え判断
			  hit = 0;
			  blow = 0;
			  for(int i = 0; i < answer.length; i++){
				  for(int j = 0; j < answer.length; j++){
					  //同じインデックスで値も同じ時 hit
					  if(i == j && input[i] == answer[j] ){
					    hit++;
					  //インデックスが違っても値が同じならblow
					  }else if(input[i] == answer[j]){
						  blow++;
					  }
				  }
			  }
			  
			  System.out.println("ヒット:" + hit +"  , ブロー:" + blow);
			  //3回ヒットで終了、それ以外は続行
			  if(hit == 3){
				  System.out.println("成功!");
				  break;
			  }else{
				  System.out.println("もう一度!");
			  }
		  }
		  
	}//mainクラスのend
	
}//ブロックのend

今後

  • これをGUIにしていきます。
  • ループ部分の記述をもう一度噛み砕いて理解
  • IOExceptionはどう入力したら出力するか
  • その他例外処理の追加など(intの範囲外の数値を入れた時など)