facebook twitter hatena line email

「Php/codeigniter/db」の版間の差分

提供: 初心者エンジニアの簡易メモ
移動: 案内検索
(SQLの実行)
 
(同じ利用者による、間の36版が非表示)
行50: 行50:
 
==="No database selected"とエラーが出る場合===
 
==="No database selected"とエラーが出る場合===
 
application/config/database.php
 
application/config/database.php
'database' => '',
+
<pre>
 +
'database' => '',
 +
</pre>
 
が空になってないか確認する。
 
が空になってないか確認する。
  
 
==SQLの実行==
 
==SQLの実行==
 +
 
参照
 
参照
$this->db->query("select * from users");
+
<pre>
 +
$query = $this->db->query('select * from users;');
 +
foreach ($query->result() as $row)
 +
{
 +
        echo $row->id;
 +
        echo $row->code;
 +
        echo $row->name;
 +
        echo $row->age;
 +
}
 +
</pre>
  
 
挿入
 
挿入
行75: 行87:
 
UNIQUE KEY `code` (`code`)
 
UNIQUE KEY `code` (`code`)
 
);
 
);
 +
</pre>
 +
 +
使用したデータ
 +
<pre>
 +
insert into users(code, name, age) values('taro', 'taro~', 10);
 +
insert into users(code, name, age) values('jiro', 'jiro~', 8);
 +
insert into users(code, name, age) values('saburo', 'saburo~', 6);
 +
insert into users(code, name, age) values('siro', 'siro~', 4);
 +
</pre>
 +
 +
==="Message: syntax error, unexpected identifier"エラーが出る時===
 +
SQL文字列を'(シングルクウォート)で囲むと、SQL文の'とかぶるので、SQLは"(ダブルクウォート)で囲む
 +
 +
==SQLエスケープ処理==
 +
シングルクウォートを自動でつける
 +
$sql = "INSERT INTO users (code) VALUES(".$this->db->escape($code).")";
 +
 +
検索時の対応は、シングルクウォートをつけられないので、escape_like_str()を使う
 +
$sql = "SELECT * FROM users (code) LIKE '%".$this->db->escape_like_str($search)."%'";
 +
 +
==SQLバインド==
 +
セキュリティを考慮するとSQL文をエスケープよりは、バインドを使うほうが、抜けがなくて良い。
 +
$sql = "SELECT * FROM users WHERE id IN ? AND code = ? AND age = ?";
 +
$this->db->query($sql, array(array(1, 6), 'taro', 10'));
 +
 +
==エラー処理==
 +
<pre>
 +
if ( ! $this->db->simple_query('SELECT `code` FROM `users`'))
 +
{
 +
        $error = $this->db->error();
 +
}
 +
</pre>
 +
 +
==Select文の色々==
 +
===最初の行取得===
 +
<pre>
 +
$query = $this->db->query('select * from users;');
 +
$row = $query->row(); // 最初の行を受け取る
 +
echo $row->id;
 +
echo $row->code;
 +
echo $row->name;
 +
echo $row->age;
 +
</pre>
 +
 +
==Insert文生成==
 +
<pre>
 +
$data = array('code' => 'saburo', 'name' => 'saburo', 'age' => 6);
 +
$sql = $this->db->insert_string('users', $data);
 +
</pre>
 +
以下SQL文が生成される
 +
INSERT INTO `users` (`code`, `name`, `age`) VALUES ('saburo', 'saburo', 6)
 +
 +
==Update文生成==
 +
<pre>
 +
$data = array('name' => 'saburo', 'age' => 6);
 +
$where = "id = 1 AND code = 'saburo'";
 +
$sql = $this->db->update_string('users', $data, $where);
 +
</pre>
 +
以下SQL文が生成される
 +
UPDATE `users` SET `name` = 'saburo', `age` = 6 WHERE `id` = 1 AND `code` = 'saburo'
 +
 +
===Where文もエスケープさせる===
 +
<pre>
 +
$data = array('name' => 'saburo', 'age' => 6);
 +
$where = array('code' => 'saburo', 'age' => 6);
 +
$sql = $this->db->update_string('users', $data, $where);
 +
</pre>
 +
以下SQL文が生成される
 +
UPDATE `users` SET `name` = 'saburo', `age` = 6 WHERE `code` = 'saburo' AND `age` = 6
 +
 +
====SQLインジェクション対応====
 +
SQLを壊すような、変な文字列を値に用意。
 +
<pre>
 +
$data = array('name' => 'saburo', 'age' => 6);
 +
$where = array('code' => "sabu'; delete from users where code <>'");
 +
$sql = $this->db->update_string('users', $data, $where);
 +
</pre>
 +
以下SQL文が生成され、ちゃんとエスケープされる
 +
<pre>
 +
UPDATE `users` SET `name` = 'saburo', `age` = 6 WHERE `code` = 'sabu\'; delete from users where code <>\''
 +
</pre>
 +
 +
SQLを壊すような、変な文字列をカラム側に用意。
 +
<pre>
 +
$data = array('name' => 'saburo', 'age' => 6);
 +
$where = array("code <>'' and code <> " => "");
 +
$sql = $this->db->update_string('users', $data, $where);
 +
</pre>
 +
以下SQL文が生成され、SQLインジェクションされてしまう・・・
 +
<pre>
 +
UPDATE `users` SET `name` = 'saburo', `age` = 6 WHERE `code` <> '' and `code` <> ''
 +
</pre>
 +
カラム側に値をいれるときは、カラム名チェックしたほうが良いですね。
 +
 +
==Select文のGet取得==
 +
<pre>
 +
// select * from users を実行できる
 +
$query = $this->db->get('users');
 +
 +
// select * from users where id = 1 limit 1, 2; を実行できる
 +
$query = $this->db->get_where('users', array('id' => 1), 1, 2);
 +
 +
// select id, code from users を実行できる
 +
$this->db->select('id, code');
 +
$query = $this->db->get('users');
 +
 +
// select id, code from users を実行できる
 +
$this->db->select('id, code');
 +
$this->db->from('users');
 +
$query = $this->db->get();
 +
</pre>
 +
 +
===Select文のGetのWhere設定===
 +
<pre>
 +
// where age = 10
 +
$this->db->where('age', 10);
 +
 +
// where age = 10 and code = 'taro'
 +
$this->db->where('age', 10);
 +
$this->db->where('code', 'taro');
 +
 +
// where age = 10 or code = 'taro'
 +
$this->db->where('age', 10);
 +
$this->db->or_where('code', 'taro');
 +
</pre>
 +
 +
===Select文のGetのその他===
 +
<pre>
 +
$this->db->order_by('code', 'DESC');
 +
 +
$this->db->group_by("code");
 +
 +
$this->db->having('age',  10);
 +
 +
$this->db->limit(10);
 +
</pre>
 +
 +
==Insert文を即実行==
 +
<pre>
 +
$data = array('code' => 'saburo', 'name' => 'saburo', 'age' => 6);
 +
$query = $this->db->insert('users', $data);
 +
</pre>
 +
 +
==Update文を即実行==
 +
<pre>
 +
$data = array('name' => 'saburo', 'age' => 6);
 +
$this->db->where('code', 'saburo');
 +
$this->db->where('age', 6);
 +
$query = $this->db->update('users', $data);
 +
 +
// where文のバインド
 +
$data = array('name' => 'saburo', 'age' => 6);
 +
$where = array('code' => 'saburo', 'age' => 6);
 +
$query = $this->db->update('users', $data, $where);
 +
</pre>
 +
 +
==Replace文実行==
 +
<pre>
 +
$data = array(
 +
        'code' => 'saburo',
 +
        'name' => 'saburo',
 +
        'age'  => '10'
 +
);
 +
$this->db->replace('users', $data);
 +
</pre>
 +
primaryキーやuniqueキーとなるカラムが、自動で条件になり、他のカラムが更新される。
 +
 +
==カラム名取得==
 +
<pre>
 +
$fields = $this->db->list_fields('users');
 +
echo print_r($fields,1);
 +
</pre>
 +
出力
 +
<pre>
 +
Array
 +
(
 +
[0] => id
 +
[1] => code
 +
[2] => name
 +
[3] => age
 +
)
 
</pre>
 
</pre>
  
 
==公式==
 
==公式==
 +
db接続関連
 
https://codeigniter.jp/user_guide/3/database/connecting.html
 
https://codeigniter.jp/user_guide/3/database/connecting.html
 +
 +
query関連
 +
https://codeigniter.jp/user_guide/3/database/helpers.html
 +
 +
select_get関連
 +
https://codeigniter.jp/user_guide/3/database/query_builder.html
 +
 +
メタ関連
 +
https://codeigniter.jp/user_guide/3/database/metadata.html

2024年11月10日 (日) 09:00時点における最新版

db自動接続

application/config/autoload.php

- $autoload['libraries'] = array();
+ $autoload['libraries'] = array('database');

手動接続

以下でデフォルトのdbに接続

$this->load->database();

db設定

application/config/database.php

以下デフォルト設定

$db['default'] = array(
	'dsn'	=> '',
	'hostname' => 'localhost',
	'username' => '',
	'password' => '',
	'database' => '',
	'dbdriver' => 'mysqli',
	'dbprefix' => '',
	'pconnect' => FALSE,
	'db_debug' => (ENVIRONMENT !== 'production'),
	'cache_on' => FALSE,
	'cachedir' => '',
	'char_set' => 'utf8',
	'dbcollat' => 'utf8_general_ci',
	'swap_pre' => '',
	'encrypt' => FALSE,
	'compress' => FALSE,
	'stricton' => FALSE,
	'failover' => array(),
	'save_queries' => TRUE
);

PDOを使う場合は以下の通りdnsを設定する

'dsn'	=> 'mysql:host=localhost;dbname=mydatabase',

usernameと、passwordと、databaseを設定する。

'username' => '',
'password' => '',
'database' => '',

"No database selected"とエラーが出る場合

application/config/database.php

'database' => '',

が空になってないか確認する。

SQLの実行

参照

$query = $this->db->query('select * from users;');
foreach ($query->result() as $row)
{
        echo $row->id;
        echo $row->code;
        echo $row->name;
        echo $row->age;
}

挿入

$this->db->query("insert into users(code, name, age) values('taro', 'taro!', 10);");
$this->db->query("insert into users(code, name, age) values('jiro', 'jiro!', 8);");

削除

$this->db->query("delete from users where code ='jiro';");

使用したtable定義

drop table users;
create table users(
id int(11) unsigned NOT NULL AUTO_INCREMENT,
code varchar(15),
name varchar(15),
age int(11) unsigned,
PRIMARY KEY(id),
UNIQUE KEY `code` (`code`)
);

使用したデータ

insert into users(code, name, age) values('taro', 'taro~', 10);
insert into users(code, name, age) values('jiro', 'jiro~', 8);
insert into users(code, name, age) values('saburo', 'saburo~', 6);
insert into users(code, name, age) values('siro', 'siro~', 4);

"Message: syntax error, unexpected identifier"エラーが出る時

SQL文字列を'(シングルクウォート)で囲むと、SQL文の'とかぶるので、SQLは"(ダブルクウォート)で囲む

SQLエスケープ処理

シングルクウォートを自動でつける

$sql = "INSERT INTO users (code) VALUES(".$this->db->escape($code).")";

検索時の対応は、シングルクウォートをつけられないので、escape_like_str()を使う

$sql = "SELECT * FROM users (code) LIKE '%".$this->db->escape_like_str($search)."%'";

SQLバインド

セキュリティを考慮するとSQL文をエスケープよりは、バインドを使うほうが、抜けがなくて良い。

$sql = "SELECT * FROM users WHERE id IN ? AND code = ? AND age = ?";
$this->db->query($sql, array(array(1, 6), 'taro', 10'));

エラー処理

if ( ! $this->db->simple_query('SELECT `code` FROM `users`'))
{
        $error = $this->db->error();
}

Select文の色々

最初の行取得

$query = $this->db->query('select * from users;');
$row = $query->row(); // 最初の行を受け取る
echo $row->id;
echo $row->code;
echo $row->name;
echo $row->age;

Insert文生成

$data = array('code' => 'saburo', 'name' => 'saburo', 'age' => 6);
$sql = $this->db->insert_string('users', $data);

以下SQL文が生成される

INSERT INTO `users` (`code`, `name`, `age`) VALUES ('saburo', 'saburo', 6)

Update文生成

$data = array('name' => 'saburo', 'age' => 6);
$where = "id = 1 AND code = 'saburo'";
$sql = $this->db->update_string('users', $data, $where);

以下SQL文が生成される

UPDATE `users` SET `name` = 'saburo', `age` = 6 WHERE `id` = 1 AND `code` = 'saburo'

Where文もエスケープさせる

$data = array('name' => 'saburo', 'age' => 6);
$where = array('code' => 'saburo', 'age' => 6);
$sql = $this->db->update_string('users', $data, $where);

以下SQL文が生成される

UPDATE `users` SET `name` = 'saburo', `age` = 6 WHERE `code` = 'saburo' AND `age` = 6

SQLインジェクション対応

SQLを壊すような、変な文字列を値に用意。

$data = array('name' => 'saburo', 'age' => 6);
$where = array('code' => "sabu'; delete from users where code <>'");
$sql = $this->db->update_string('users', $data, $where);

以下SQL文が生成され、ちゃんとエスケープされる

UPDATE `users` SET `name` = 'saburo', `age` = 6 WHERE `code` = 'sabu\'; delete from users where code <>\'' 

SQLを壊すような、変な文字列をカラム側に用意。

$data = array('name' => 'saburo', 'age' => 6);
$where = array("code <>'' and code <> " => "");
$sql = $this->db->update_string('users', $data, $where);

以下SQL文が生成され、SQLインジェクションされてしまう・・・

UPDATE `users` SET `name` = 'saburo', `age` = 6 WHERE `code` <> '' and `code` <> ''

カラム側に値をいれるときは、カラム名チェックしたほうが良いですね。

Select文のGet取得

// select * from users を実行できる
$query = $this->db->get('users');

// select * from users where id = 1 limit 1, 2; を実行できる
$query = $this->db->get_where('users', array('id' => 1), 1, 2);

// select id, code from users を実行できる
$this->db->select('id, code');
$query = $this->db->get('users');

// select id, code from users を実行できる
$this->db->select('id, code');
$this->db->from('users');
$query = $this->db->get();

Select文のGetのWhere設定

// where age = 10
$this->db->where('age', 10);

// where age = 10 and code = 'taro'
$this->db->where('age', 10);
$this->db->where('code', 'taro');

// where age = 10 or code = 'taro'
$this->db->where('age', 10);
$this->db->or_where('code', 'taro');

Select文のGetのその他

$this->db->order_by('code', 'DESC');

$this->db->group_by("code");

$this->db->having('age',  10);

$this->db->limit(10);

Insert文を即実行

$data = array('code' => 'saburo', 'name' => 'saburo', 'age' => 6);
$query = $this->db->insert('users', $data);

Update文を即実行

$data = array('name' => 'saburo', 'age' => 6);
$this->db->where('code', 'saburo');
$this->db->where('age', 6);
$query = $this->db->update('users', $data);

// where文のバインド
$data = array('name' => 'saburo', 'age' => 6);
$where = array('code' => 'saburo', 'age' => 6);
$query = $this->db->update('users', $data, $where);

Replace文実行

$data = array(
        'code' => 'saburo',
        'name' => 'saburo',
        'age'  => '10'
);
$this->db->replace('users', $data);

primaryキーやuniqueキーとなるカラムが、自動で条件になり、他のカラムが更新される。

カラム名取得

$fields = $this->db->list_fields('users');
echo print_r($fields,1);

出力

Array
(
[0] => id
[1] => code
[2] => name
[3] => age
)

公式

db接続関連 https://codeigniter.jp/user_guide/3/database/connecting.html

query関連 https://codeigniter.jp/user_guide/3/database/helpers.html

select_get関連 https://codeigniter.jp/user_guide/3/database/query_builder.html

メタ関連 https://codeigniter.jp/user_guide/3/database/metadata.html