官方demo给出的用法:

Doo::db()->find(‘post’);

我一般这么用:

Doo::loadModel(‘Users’);
$users=new users;
$users=$this->db()->find($users);

或者:

Doo::loadModel(‘Users’);
$users=new users;
$users->find();

find()方法有个可选参数$opt,update,insert,delete方法也有,$opt是个关联数组,具体支持的索引参见API文档。
update方法的$opt参数支持的索引文档没有列出,我这里补充下: 支持where,limit
下面我给些操作实例
count方法

$this->load()->model(‘Posts ‘);
$posts=new posts;
$posts->count(array(‘where’=>’post_type=”post”‘));

update方法

Doo::loadModel(‘Posts’);
$post=new posts;
$post->title=’new_title’;
$int_affectedrows=$this->db()->update($post,array(‘where’=>”ID=$id”));

insert方法

Doo::loadModel(‘Posts’);
$post=new posts;
$post->title=’title’;
$post->content=’content’;
//……..
$int_id=$this->db()->insert($post);

delete方法

Doo::loadModel(‘Posts’);
$posts= new posts;
//$ids=”(‘1’,‘2’)”;
$posts->delete(array(‘where’=>”ID IN ($ids)”));

relate方法
index.php

Doo::db()->setMap($dbmap);

这里取消注释
db.conf.php 里添加数据模型的关系

$dbmap[‘TermTaxonomy’][‘belongs_to’][‘Terms’] = array(‘foreign_key’=>’term_id’);
$dbmap[‘Terms’][‘has_one’][‘TermTaxonomy’] = array(‘foreign_key’=>’term_id’);

然后是controller里的语句,注意relate会判断后加载模型不需要手动loadModel

$opt=array(
‘where’=>’taxonomy=”category”‘,
‘asArray’=>true,
‘filters’=>array(
array(‘model’=>’TermTaxonomy’,
‘where’=>’count!=0’)
)
);
$categories=$this->db()->relate(‘TermTaxonomy’,’Terms’,$opt);

1,目录结构更改
由于DooPHP的目录层次比较深(相对我这样一个人前后端都独立来写而言),来回切换目录很麻烦,所以最好是将protected目录及此目录下的global拆分。protected目录移动有官方的教程,参见如何把protected目录移到web root以外

global因为是静态资源可以直接移动。
2,表前缀及generate mode操作
如果数据库表有前缀又不想改表名或每次loadModel都要写上带前缀的参数,可以在dooframework/db/DooModelGen.php里修改gen_mysql和genMySQL函数,

public static function gen_mysql($comments=true, $vrules=true, $extends='DooModel', $createBase=true, $baseSuffix='Base', $chmod=null, $path=null,$tablePrefix=null) {
    self::genMySQL($comments, $vrules, $extends, $createBase, $baseSuffix, $chmod, $path,$tablePrefix);
}


 public static function genMySQL($comments=true, $vrules=true, $extends='DooModel', $createBase=true, $baseSuffix='Base', $chmod=null, $path=null,$tablePrefix=null) 

在95行$classname=’’;下增加

if($tablePrefix){
                    $temptbl = str_replace($tablePrefix,'',$tblname);
                }else{
                     $temptbl = $tblname;
                                        }

然后在你所开发的应用目录下,修改yourapp/controller/MainController.php gen_model函数

public function gen_model(){
Doo::loadCore(‘db/DooModelGen’);
DooModelGen::genMySQL(true,true, ‘DooModel’, false, ‘Base’, null,null,’wp_’);
}

DooModelGen::genMySQL的最后一个参数即为表前缀,’wp_’是wordpress安装时默认的表前缀。 3,数据库持久连接 config/db.conf.php 的注释示例写的都是使用持久连接,数组的最后一项都为true,这会造成一些问题。您可能像我一样没注意这最后一项,其实注释上面几行有这样一行说明$dbconfig[ Environment or connection name] = array(Host, Database, User, Password, DB Driver, Make Persistent Connection?); 持久连接依赖于服务器php.ini设置,mysql.allow_persistent 默认为”1” 但也可能被服务器管理员修改。所以如果出现数据库连接失败试试把true改为false.

/* $dbconfig[‘dev’] = array(‘localhost’, ‘database’, ‘root’, ‘1234’, ‘mysql’, true);
* $dbconfig[‘prod’] = array(‘localhost’, ‘database’, ‘root’, ‘1234’, ‘mysql’, true);
*/

getUserMedia API属于 WebRTC 的一个。 浏览器支持情况:WebRTC 需要Chrome 18.0.1008+ 在 about:flags里启用. Chrome 21默认开启, Opera 12 Firefox 17 好了,多的不说,直接上代码了。需要说明的地方都写在注释里了。 demo示例: http://static.bungos.me/demos/html5_getUserMedia/

window.URL = window.URL || window.webkitURL || window.msURL || window.oURL;
// 给video的src赋值时会用到window.URL的createObjectURL方法,这里统一接口。
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;

var video=document.querySelector('video'),permited=false;

function snapshot() {
  if (!permited) {accessLocalWebCam();return false;}
  document.querySelector('audio').play();
  var canvas=document.querySelector('canvas');
  canvas.height=video.videoHeight;
  canvas.width=video.videoWidth;
  //canvas的宽高与video原始宽高保持一致,而不是video的可见宽高,否则无法截取完整画面。
  canvas.getContext('2d').drawImage(video,0,0);
  var img=document.querySelector('#pic img') || document.createElement('img');
  img.src = canvas.toDataURL('image/png');
  // "image/webp" works in Chrome 18. In other browsers, this will fall back to image/png.
  img.width=400;
  img.height=300;
  document.getElementById('pic').appendChild(img);
}

document.getElementById('camera').addEventListener('click', snapshot, false);

function successsCallback(stream) {
  permited=true;
  video.src = window.URL.createObjectURL(stream) || stream;
  //分别针对其他浏览器和firefox进行赋值操作。
}

function accessLocalWebCam() {
  try {
    navigator.getUserMedia('video', successsCallback,  function (err) {
      //也可以同时请求{audio:true, video:true}
  console.log(err);
});
  } catch (err) {
    console.log(err);
  }
}

if (!navigator.getUserMedia) {
console.log(‘不支持 getUserMedia 接口’);
} else {
document.querySelector(‘button’).addEventListener(‘click’, accessLocalWebCam, false);
}

参考文献: Capturing Audio & Video in HTML5 - HTML5 Rocks

开发时需要注意的事项: 1、需要通过http访问实现,也就是不能通过文件浏览方式。 2、requestPermission必须由用户交互触发,直接执行不会有任何效果。 demo示例请点击下方评论框的“(如有回复通知我)”虽然连回复评论都还没做。init函数的console.log只为调试而用,可以移除。采用原型+构造函数的模式封装了下,代码可以移至外部JS文件,调用方式在最下面三行。instance的notification对象可以通过instance.msg取得,可添加ondisplay,onerror,onclose,onclick的事件监听。我所使用的chrome在调试时发现notification对象亦有onshow事件,这只是与ondisplay的名称不一样而已。是标准化的名称。封装的不够完善,还想通过参数判断来实现createHTMLNotification,先这样了。 API文档参考,来自chromium的关于Notification的API文档API Specification

function Notifier(icon,title,info){
var self=this;
this.icon=icon;
this.title=title;
this.info=info;
this.init();
this.show=function(){
if(self.checkPermission()==0){
self.msg=self.create(self.icon,self.title,self.info);
self.msg.show();
}else{self.requestPermission(self.show);}

};
}
Notifier.prototype={
constructor:Notifier,
center:(window.Notifications || window.webkitNotifications),
checkPermission:function(){var p=this.center.checkPermission();return p},
requestPermission:function(cb){this.center.requestPermission(cb);
},
create:function(icon,title,info){var o=this.center.createNotification(icon,title,info);return o;},
show:function(){},
init:function(){var permission = this.center.checkPermission();
if (permission == 0) {
console.log (‘您已接受来自网站的通知!’);
this.show();
} else if (permission == 1) {
console.log (‘请点击“允许”按钮,以接受来自网站的通知’);
this.requestPermission(this.show);
} else {

    //用户不允许Notification事件
   console.log ( '您已选择禁止本页面显示网页通知!');
}}

};
n=new Notifier(‘http://fan16.net/favicon.ico', “您已接受来自番石榴的通知!”,”有新消息时将会通知您。”);
var b=document.getElementById(‘showButton’);
b.addEventListener(‘click’, function(){ n.init();}, false);

查看网上流传的CSS2手册,发现background-position定义了两个参数:length,position ,分别指由百分比或长度单位指定的值和由left,top,right,bottom指定的值。而另外一些网上的资料则将这俩参数都归并为可能的值,我以为这样跟合理一些,因为他们都完成同样的任务。但有些稍稍不同的是当值指定为百分比时的计算方式,当值指定为百分比时计算方式为element 的宽或高减去image 的宽或高,所得差乘以指定的百分比,例如:element高为20px image高为10px 当y值指定为100%时,实际的偏移值为(20-10)*1

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×