Xweibo微博广场上传图片bug修复

选中图片触发input change事件后会请求到application/controllers/api/weibo/action.mod.php

执行upload_pic方法

function upload_pic()
{
$callback = V(‘g:callback’,’’);
if(!preg_match(‘/^[.a-zA-Z0-9_]+$/‘,$callback)){
$callback = ‘callback’;
}
$redirect = ‘window.location=”‘.W_BASE_URL.’js/blank.html?rand=’.rand(1,PHP_INT_MAX) . ‘“‘;

    if (isset($_FILES\['pic'\])) {
        if ($_FILES\['pic'\]\['error'\]) {
            switch ($_FILES\['pic'\]\['error'\]) {
                case '1':
                    $err = APP::ajaxRst(false, '2010009', 'The uploaded file exceeds the upload\_max\_filesize directive in php.ini', true);
                    break;
                case '2':
                    $err = APP::ajaxRst(false, '2010010', 'The uploaded file exceeds the MAX\_FILE\_SIZE directive that was specified in the HTML form', true);
                    break;
                case '3':
                    $err = APP::ajaxRst(false, '2010011', 'The uploaded file was only partially uploaded', true);
                    break;
                case '4':
                    $err = APP::ajaxRst(false, '2010012', 'No file was uploaded', true);
                    break;
                case '6':
                    $err = APP::ajaxRst(false, '2010013', 'Missing a temporary folder', true);
                    break;
                case '7':
                    $err = APP::ajaxRst(false, '2010014', 'Failed to write file to disk', true);
                    break;
            }
            die("");
        } else {
                $has_pic = false;

    if (isset($\_FILES\['pic'\]) && !empty($\_FILES\['pic'\])) {

        if(!empty($\_FILES\['pic'\]\['tmp\_name'\])){
            $\_pathinfo = GetImageSize($\_FILES\['pic'\]\['tmp_name'\]);
            if(empty($\_pathinfo) || $\_pathinfo\[2\] < 1 || $_pathinfo\[2\] > 16 ){
                $_FILES\['pic'\]\['error'\] = 6666;
            }
        }

        if ($_FILES\['pic'\]\['error'\]) {
            if(IS\_IN\_API_REQUEST){
                APP::ajaxRst(false, '2010014', 'UPLOAD\_ERROR:'. $\_FILES\['pic'\]\['error'\]);
            }else{
                $err = APP::ajaxRst(false, '2010014', 'UPLOAD\_ERROR:'. $\_FILES\['pic'\]\['error'\], true);
                die("");
            }

        }
        $has_pic = true;
    }
        if($has_pic){
            $fileName = 'weibo\_img\_strategy_'. time(). '_'. uniqid('', true);
            $file_obj = APP::ADP('upload');
            $fileName = 'weibo\_img\_strategy_'. time(). '_'. uniqid('', true);
            if (!$file_obj->upload('pic', $fileName, FALSE, 'jpg,jpeg,gif,png')) {
                if(IS\_IN\_API_REQUEST){
                    APP::ajaxRst(false, '2010014', 'strategy\_UPLOAD\_ERROR');
                }else{
                    $err = APP::ajaxRst(false, '2010014', 'strategy\_UPLOAD\_ERROR', true);
                    die("");
                }
            }

            //获取上传文件的信息
            $\_image = $file\_obj->getUploadFileInfo();
            $e\_params\['\_upload\_pic\_url'\] = $_image\['webpath'\];

                /*$desPath=$\_SERVER\["DOCUMENT\_ROOT"\]."/data/".$fileName;
             move\_uploaded\_file($\_FILES\['pic'\]\['tmp\_name'\],$desPath);
             $url = 'http://t.quanjinglian.com/'."data/".$fileName;*/
        }


            $result = DR('xweibo/xwb.uploadPic', '',$_image\['webpath'\]);

            //$result = DR('xweibo/xwb.uploadPic', '', $\_FILES\['pic'\]\['tmp\_name'\]);
        }
    } else {
        die("");
    }

    if (!empty($result\['errno'\])) {
        die("");
    }

    $json = array();
    $result = $result\['rst'\];
    $json\['msg'\] = $_image\['webpath'\];

    die("");
}

$result = DR(‘xweibo/xwb.uploadPic’, ‘’,$_image[‘webpath’]);

在这行会转到application/class/weibo.class.php 执行uploadPic方法,该方法已经被官方废弃,$pic参数即刚刚传的$_image[‘webpath’],一个图片网址,上传在自己的服务器上的。

 function uploadPic($pic)
 {

    $response=array(
        'errno'=>0,
        'err'=>'',
        'rst'=>array('msg'=>$pic)
        );
    //echo $\_GET\['callback'\].'('.json\_encode($response).');';
    return $response;
 }返回正确的JSON格式就好了

然后点击发布转入执行action.mod.php的update方法,此时的传递过来的pic变量是个字符串而不是先前需要处理的$_FIELS[‘pic’] 在线访谈的页面是直接提交到这个update方法的所以对于上传的图片处理还不能去掉也要与现在这个pic变量区别开来 通过下面的方法获取图片网址

$picurl=V(‘p:pic’, ‘’);

if($picurl){
$has_pic=true;
}

Read More

DooPHP 数据库常用操作 DooSqlMagic类

官方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”));

Read More

基于DooPHP开发网站的一些初始设定

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);
*/

Read More

HTML5 getUserMedia API 开发指南

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

Read More

HTML5 notification 实现详解附实例教程

开发时需要注意的事项: 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);

Read More

css background-position 值设为百分比时定位方式的不同

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

Read More