「Php/codeigniter/db」の版間の差分
(→Replace文実行) |
|||
(同じ利用者による、間の9版が非表示) | |||
行108: | 行108: | ||
==SQLバインド== | ==SQLバインド== | ||
− | + | セキュリティを考慮するとSQL文をエスケープよりは、バインドを使うほうが、抜けがなくて良い。 | |
$sql = "SELECT * FROM users WHERE id IN ? AND code = ? AND age = ?"; | $sql = "SELECT * FROM users WHERE id IN ? AND code = ? AND age = ?"; | ||
$this->db->query($sql, array(array(1, 6), 'taro', 10')); | $this->db->query($sql, array(array(1, 6), 'taro', 10')); | ||
行148: | 行148: | ||
UPDATE `users` SET `name` = 'saburo', `age` = 6 WHERE `id` = 1 AND `code` = 'saburo' | UPDATE `users` SET `name` = 'saburo', `age` = 6 WHERE `id` = 1 AND `code` = 'saburo' | ||
− | === | + | ===Where文もエスケープさせる=== |
<pre> | <pre> | ||
$data = array('name' => 'saburo', 'age' => 6); | $data = array('name' => 'saburo', 'age' => 6); | ||
行156: | 行156: | ||
以下SQL文が生成される | 以下SQL文が生成される | ||
UPDATE `users` SET `name` = 'saburo', `age` = 6 WHERE `code` = 'saburo' AND `age` = 6 | 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取得== | ==Select文のGet取得== | ||
行228: | 行252: | ||
$this->db->replace('users', $data); | $this->db->replace('users', $data); | ||
</pre> | </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> | ||
==公式== | ==公式== | ||
行239: | 行279: | ||
select_get関連 | select_get関連 | ||
https://codeigniter.jp/user_guide/3/database/query_builder.html | 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