今日1.1の目標
- クッキー技術の実装をつかみ、
- マスターシナリオクッキー終了。
- クッキーの有効期間を理解し、制御します。
- 理解と制御クッキーの範囲;
- 理解とクロスドメインクッキーのアクセスの制御。
1.2 SQLパッケージ
各機能は、SQL文を記述する必要があり、パッケージの普遍的な方法は、我々はすべてのテーブルを操作することができます
1.2.1は、挿入文を生成します
<?php
$table='products'; //表名
//插入的数据
$data['proid']='111';
$data['proname']='钢笔';
$data['proprice']=120;
//第一步:拼接字段名
$keys=array_keys($data); //获取所有的字段名
$keys=array_map(function($key){ //在所有的字段名上添加反引号
return "`{$key}`";
},$keys);
$keys=implode(',',$keys); //字段名用逗号连接起来
//第二步:拼接值
$values=array_values($data); //获取所有的值
$values=array_map(function($value){ //所有的值上添加单引号
return "'{$value}'";
},$values);
$values=implode(',',$values); //值通过逗号连接起来
//第三步:拼接SQL语句
echo $sql="insert into `{$table}` ($keys) values ($values)";
要約:
1、array_keys:取得キー配列
2、array_values:配列の値を取得
図3は、array_mapを():アレイは、順番に各要素は、コールバック関数を呼び出します。
生成された1.2.2アップデートステートメント
<?php
$table='products'; //表名
$data['proname']='钢笔';
$data['proprice']=120;
$data['proID']='111';
//获取主键
function getPrimaryKey($table) {
//连接数据库
$link=mysqli_connect('localhost','root','root','data');
mysqli_set_charset($link,'utf8');
//查看表结构
$rs=mysqli_query($link,"desc `{$table}`");
//循环判断主键
while($rows=mysqli_fetch_assoc($rs)){
if($rows['Key']=='PRI')
return $rows['Field'];
}
}
//第一步:获取非主键
$keys=array_keys($data); //获取所有键
$pk=getPrimaryKey($table); //获取主键
$index=array_search($pk,$keys); //返回主键在数组中的下标
unset($keys[$index]); //删除主键
//第二步:拼接`键`='值'的形式
$keys=array_map(function($key) use ($data){
return "`{$key}`='{$data[$key]}'";
},$keys);
$keys=implode(',',$keys);
//第三步:拼接SQL语句
echo $sql="update `{$table}` set $keys where $pk='{$data[$pk]}'";
1.2.3生成されたselect文
<?php
/**
*$table string 表名
*$cond array 条件
*/
function select($table,$cond=array()) {
$sql="select * from `{$table}` where 1";
//拼接条件
if(!empty($cond)){
foreach($cond as $k=>$v){
if(is_array($v)){ //条件的值是数组类型
switch($v[0]){ //$v[0]保存的是符号,$v[1]是值
case 'eq': //等于 equal
$op='=';
break;
case 'gt': //大于 greater than
$op='>';
break;
case 'lt':
$op='<';
break;
case 'gte':
case 'egt':
$op='>=';
break;
case 'lte':
case 'elt':
$op='<=';
break;
case 'neq':
$op='<>';
break;
}
$sql.=" and `$k` $op '$v[1]'";
}else{
$sql.=" and `$k`='$v'";
}
}
}
return $sql;
}
//测试
$table='products'; //表名
$cond=array(
'proname' => '钢笔',
'proprice' => array('eq','12'),
'aa' => array('gt',10),
'bb' => array('lt',20),
);
echo select($table),'<br>';
echo select($table,$cond);
1.2.4は、テーブル名を取得します。
<?php
namespace Core;
class Model {
private $table;
public function __construct($table='') {
if($table!='') //直接给基础模型传递表名
$this->table=$table;
else { //实例化子类模型
$this->table=substr(basename(get_class($this)),0,-5);
}
echo $this->table,'<br>';
}
}
namespace Model;
class ProductsModel extends \Core\Model{
}
namespace Controller\Admin;
new \Core\Model('news'); //news
new \Model\ProductsModel(); //Products
要約:
1、get_class():(名前空間を含む)オブジェクトのクラスを取得します。
図2は、SUBSTR():文字列、採取-5文字列の最後の5つの文字は無視されていることを示し
1.2.5プロジェクトの追加、削除、変更ユニバーサルパッケージ、
カプセル化のすべてのテーブルを操作することができるので、これらの方法は、ベースモデルに封入することができます
<?php
namespace Core;
//基础模型
class Model {
protected $mypdo;
private $table; //表名
private $pk; //主键
public function __construct($table='') {
$this->initMyPDO();
$this->initTable($table);
$this->getPrimaryKey();
}
//连接数据库
private function initMyPDO() {
$this->mypdo= MyPDO::getInstance($GLOBALS['config']['database']);
}
//获取表名
private function initTable($table){
if($table!='') //直接给基础模型传递表名
$this->table=$table;
else { //实例化子类模型
$this->table=substr(basename(get_class($this)),0,-5);
}
}
//获取主键
private function getPrimaryKey() {
$rs=$this->mypdo->fetchAll("desc `{$this->table}`");
foreach($rs as $rows){
if($rows['Key']=='PRI'){
$this->pk=$rows['Field'];
break;
}
}
}
//万能的插入
public function insert($data){
$keys=array_keys($data); //获取所有的字段名
$keys=array_map(function($key){ //在所有的字段名上添加反引号
return "`{$key}`";
},$keys);
$keys=implode(',',$keys); //字段名用逗号连接起来
$values=array_values($data); //获取所有的值
$values=array_map(function($value){ //所有的值上添加单引号
return "'{$value}'";
},$values);
$values=implode(',',$values); //值通过逗号连接起来
$sql="insert into `{$this->table}` ($keys) values ($values)";
return $this->mypdo->exec($sql);
}
//万能的更新
public function update($data){
$keys=array_keys($data); //获取所有键
$index=array_search($this->pk,$keys); //返回主键在数组中的下标
unset($keys[$index]); //删除主键
$keys=array_map(function($key) use ($data){
return "`{$key}`='{$data[$key]}'";
},$keys);
$keys=implode(',',$keys);
$sql="update `{$this->table}` set $keys where $this->pk='{$data[$this->pk]}'";
return $this->mypdo->exec($sql);
}
//删除
public function delete($id){
$sql="delete from `{$this->table}` where `{$this->pk}`='$id'";
return $this->mypdo->exec($sql);
}
//查询,返回二维数组
public function select($cond=array()){
$sql="select * from `{$this->table}` where 1";
if(!empty($cond)){
foreach($cond as $k=>$v){
if(is_array($v)){ //条件的值是数组类型
switch($v[0]){ //$v[0]保存的是符号,$v[1]是值
case 'eq': //等于 equal
$op='=';
break;
case 'gt': //大于 greater than
$op='>';
break;
case 'lt':
$op='<';
break;
case 'gte':
case 'egt':
$op='>=';
break;
case 'lte':
case 'elt':
$op='<=';
break;
case 'neq':
$op='<>';
break;
}
$sql.=" and `$k` $op '$v[1]'";
}else{
$sql.=" and `$k`='$v'";
}
}
}
return $this->mypdo->fetchAll($sql);
}
//查询,返回一维数组
public function find($id){
$sql="select * from `{$this->table}` where `{$this->pk}`='$id'";
return $this->mypdo->fetchRow($sql);
}
}
1.2.6プロジェクト変更
1. DeleteメソッドProductsModelクラス
<?php
namespace Model;
//products模型用来操作products表
class ProductsModel extends \Core\Model{
}
図2に示すように、制御方式で直接ベースモデルを呼び出します
class ProductsController{
use \Traits\Jump;
//获取商品列表
public function listAction() {
//实例化模型
$model=new \Model\ProductsModel();
$list=$model->select();
//加载视图
require __VIEW__.'products_list.html';
}
//删除商品
public function delAction() {
$id=(int)$_GET['proid']; //如果参数明确是整数,要强制转成整形
$model=new \Model\ProductsModel();
if($model->delete($id))
$this->success('index.php?p=Admin&c=Products&a=list', '删除成功');
else
$this->error('index.php?p=admin&c=Products&a=list', '删除失败');
}
...
1.3仕事は達成するために
1.3.1追加アイテム
ステップ:
1、ページを作成するためのアイテムを追加
2、論理を達成するために追加されました
コードの実装
図1に示すように、入口(products_list.html)
<a href="index.php?p=Admin&c=Products&a=add">添加商品</a>
図2に示すように、コントローラ(ProductsController)
public function addAction(){
//执行添加逻辑
if(!empty($_POST)){
$model=new \Core\Model('products');
if($model->insert($_POST))
$this->success ('index.php?p=Admin&c=Products&a=list', '插入成功');
else
$this->error ('index.php?p=Admin&c=Products&a=add', '插入失败');
}
//显示添加页面
require __VIEW__.'products_add.html';
}
3、モデル
无
4、ビュー:ビューでproducts_add.htmlページを作成し、\ Adminディレクトリ
<body>
<form method="post" action="">
名称: <input type="text" name="proname"> <br />
价格: <input type="text" name="proprice"> <br />
<input type="submit" value="提交">
</form>
</body>
1.3.2の変更製品
ステップ:
1、変性インターフェース
2、修正ロジックを実行
コードの実装
図1に示すように、入口(products_list.html)
<a href="index.php?p=Admin&c=Products&a=edit&proid=<?=$rows['proID']?>">修改</a>
図2に示すように、コントローラ(ProductsController)
public function editAction(){
$proid=$_GET['proid']; //需要修改的商品id
$model=new \Core\Model('products');
//执行修改逻辑
if(!empty($_POST)){
$_POST['proID']=$proid;
if($model->update($_POST))
$this->success ('index.php?p=Admin&c=Products&a=list', '修改成功');
else
$this->error ('index.php?p=Admin&c=Products&a=edit&proid='.$proid, '修改失败');
}
//显示商品
$info=$model->find($proid);
require __VIEW__.'products_edit.html';
}
3、モデル
无
4、ビュー:ビューでproducts_edit.htmlを作成します\ adminディレクトリ
<body>
<form method="post" action="">
名称: <input type="text" name="proname" value='<?=$info['proname']?>'> <br />
价格: <input type="text" name="proprice" value='<?=$info['proprice']?>'> <br />
<!--
<input type="hidden" name="proID" value=<?=$info['proID']?>>
-->
<input type="submit" value="提交">
</form>
1.4クッキー
反射:Aのページ変数、Bページへのアクセスを提供している場合
方法の一つ:ファイルを含めます
方法2:GETまたはPOST提出
方法3:クライアントのファイル情報に格納されたクッキー、クッキー
1.4.1原則
クッキーは、クライアントの情報パケット(ファイル)に保存されています
ヘッダ()による応答ヘッダ、ますsetcookie()操作
構文:ヘッダ(キー:値)
<?php
header('content-type:charset=gbk');
header('name:tom');
ますsetcookie()関数:レスポンスヘッダにクライアントに送信された値、およびクライアントに保存されました。
1.4.2は、クッキーを設定します
<?php
setcookie('name','tom'); //将name=tom放到响应头中
レスポンスのヘッダ情報は、クッキーに見ることができます
クライアントがcookei情報を有した後、各リクエストサーバは、情報サーバへクッキー要求ヘッダが配置され、自動的であろう。
1.4.3は、Cookieの値を取得します。
<?php
echo $_COOKIE['name']; //从请求头中获取名字是name的cookie
注意:
1の後、ブラウザを閉じ、クッキーが消えました。このクッキーは、一時的なクッキーと呼ばれています
2は、クッキー情報が異なるブラウザではなく、クロスブラウザ間で共有されていません。
質問:なぜは通常の第二実行、初めて次のコードが実行されるエラーであります
<?php
setcookie('name','tom');
echo $_COOKIE['name']; //在请求头中获取name的cookie
ので:最初の訪問のリクエストヘッダがクッキーではないクッキーが第二の訪問に最初のセットに対応して設定されている最初の時間は、自動的にクッキー情報を配置しますので、とても低い第2の訪問より取得リクエストヘッダは、第二の訪問は、Cookieの値を取得することができます
1.4.4永続的なCookie
注:ブラウザのクッキー値を閉じた後に消えません
シナリオ:
構文:永久的なクッキーでクッキーの有効期限を追加、有効期限は、タイムスタンプを入力するための時間です
$time=time()+3600;
setcookie('name','tom',$time); //cookie的有效时间是3600秒
1.4.5クッキーは有効なディレクトリであります
現在のディレクトリとサブディレクトリ内の効果的なデフォルトのクッキー
クッキーは、ステーション全体で一般的に有効に配置されました
setcookie('name','tom',0,'/'); // /表示根目录
1.4.6サポートサブドメイン
シーン:各ドメイン名のウェブサイトのためのコードは、サイト間のクッキーは、お互いにアクセスできません。
質問:より多くのBaiduのサイトの下の2人のドメイン名よりもあり、そのクッキーはどのように、共有することがありますか?
<?php
setcookie('name','tom',0,'/','baidu.com'); //在baidu.com域名下都有效
?>
<a href="http://www.bb.baidu.com/bb.php">跳转</a>
1.4.7それは安全な輸送です
HTTPS安全な送信が送信されます。
HTTPとHTTPSのデフォルトでクッキーを転送することができます
setcookie('name','tom',0,'/','',true); // true表示只能是https传输
1.4.8訪問することは安全です
デフォルトでは、PHPとJSはクッキーにアクセスすることができます
セキュアなアクセス:PHPがアクセスできる、JSのデフォルトはfalseではありません。
PHPコード
<?php
setcookie('name','tom',0,'/','',false,true);
?>
<a href="/5-demo2.php">跳转</a>
htmlコード
<?php
echo $_COOKIE['name'],'<br>'; //PHP获取cookie
?>
<script type="text/javascript">
document.write(document.cookie); //js获取cookie
</script>
1.4.9削除クッキー
注:クッキーは数値と文字列を保存することができます。
<?php
//setcookie('name',false); //删除cookie方法一
//setcookie('name'); //删除cookie方法二
setcookie('name','tom',time()-1); //删除cookie方法三
欠点1.4.10クッキー
1、セキュリティが低いので、あなたは、ブラウザでCookieの値を見ることができるので、
2、唯一の文字列を格納番号ので、制御性が悪いです
図3に示すように、データは、要求ヘッダで送信するので、増加したデータのロード時間に対する要求。
データがブラウザに格納されているため、図4に示すように、ブラウザ格納吸入空間は、典型的には、4K、制限されます。