第九区

一个程序员的经验笔记

2015年11月1日
发表者 will
暂无评论

Yii2的小部件widgets应用

Yii2的小部件widgets用于在视图中显示一些可重用的内容。小部件基本上都是在views视图中使用的。Yii2官方提供了很多小部件,基本的小部件有:

  1. ActiveField
  2. ActiveForm
  3. ActiveFormAsset
  4. BaseListView
  5. Block
  6. Breadcrumbs
  7. ContentDecorator
  8. DetailView
  9. FragmentCache
  10. InputWidget
  11. LinkPager
  12. LinkSorter
  13. ListView
  14. MaskedInput
  15. MaskedInputAsset
  16. Menu
  17. Pjax
  18. PjaxAsset
  19. Spaceless

为bootstrap设计的小部件有:

  1. ActiveField
  2. ActiveForm
  3. Alert
  4. Button
  5. ButtonDropdown
  6. ButtonGroup
  7. Carousel
  8. Collapse
  9. Dropdown
  10. Modal
  11. Nav
  12. NavBar
  13. Progress
  14. Tabs
  15. Widget

另外,还有一些地方用到了小部件,如captcha等,都使用或扩展了基本的小部件来实现更多的功能。

所有小部件都基于widget扩展,widget类库的常用方法有:

[table id=2 /]

小部件的展示方式有两种,一种是直接展示小部件的内容,比如一个日期选择器:

<?php
use yii\jui\DatePicker;
?>
<?= DatePicker::widget([
    'model' => $model,
    'attribute' => 'from_date',
    'language' => 'zh_CN',
    'clientOptions' => [
        'dateFormat' => 'yy-mm-dd',
    ],
]) ?>

将直接显示选择器的特效

另一种则可在yii\base\Widget::begin() 和 yii\base\Widget::end() 调用中使用数据内容,比如一个表单里会有很多表单元素,表单控件需要显示的只是表单头尾的内容,中间的数据可以自由定义:

<?php
use yii\widgets\ActiveForm;
use yii\helpers\Html;
?>

<?php $form = ActiveForm::begin(['id' => 'login-form']); ?>

    <?= $form->field($model, 'username') ?>

    <?= $form->field($model, 'password')->passwordInput() ?>

    <div class="form-group">
        <?= Html::submitButton('Login') ?>
    </div>

<?php ActiveForm::end(); ?>

自己写这两种小部件的代码其实差不多,第一种比较简单:

namespace backend\libs;
use yii\base\Widget;
use yii\helpers\Html;

class HelloWidget extends Widget
{
    public $message;

    public function init()
    {
        parent::init();
        if ($this->message === null) {
            $this->message = 'Hello World';
        }
    }

    public function run()
    {
        return Html::encode($this->message);//关键代码就是直接显示而已
    }
}

第二种和第一种代码的区别请注意代码中的注释:

namespace app\components;

use yii\base\Widget;
use yii\helpers\Html;

class HelloWidget extends Widget
{
    public function init()
    {
        parent::init();
        ob_start();//截获中间部分的显示内容
    }

    public function run()
    {
        $content = ob_get_clean();//获取中间自定义的显示内容,然后可以任意处理
        return Html::encode($content);//显示全部内容
    }
}

小部件的开发就这样完成了。

2015年10月27日
发表者 will
暂无评论

开发Yii2过滤器并通过behaviors()行为调用

在Yii2的几乎每个controller中,我们都会看到一个函数behaviors(),通常,我们用这个函数来配置控制器的权限,例如:

public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::className(),//过滤器
                'rules' => [
                    [
                        'actions' => ['login', 'error','index'],
                        'allow' => true,
                    ],
                    [
                        'actions' => ['logout'],
                        'allow' => true,
                        'roles' => ['@'],
                    ],
                ],
            ],
            'verbs' => [
                'class' => VerbFilter::className(),//过滤器
                'actions' => [
                    'logout' => ['post'],
                ],
            ],
        ];
    }

注意代码中加亮的两行,这里调用的类,我们都称之为过滤器。在controller中调用过滤器,可以控制当前controller中的所有action,我们也可以在模块(module)或是应用主体中调用,来控制整个模块或是整个应用。

Yii2提供了如下过滤器:

  1. AccessControl
  2. ContentNegotiator
  3. Cors
  4. HttpCache
  5. PageCache
  6. RateLimiter
  7. AuthMethod

模仿这些过滤器,我们也可以开发自己的过滤器。

还是把测试的过滤器放到frontend/libs里,新建文件frontend/libs/TestFilter.php

<?php
namespace frontend\libs;
use Yii;
use yii\base\Action;
use yii\base\ActionFilter;
class TestFilter extends ActionFilter
{
    //在action之前运行,可用来过滤输入
    public function beforeAction($action) {
        echo '在调用action前显示<br/>';
        return TRUE;//如果返回值为false,则action不会运行
    }
    //在action之后运行,可用来过滤输出
    public function afterAction($action, $result) {
        return $result.'在调用action后显示<br/>';//可以对action输出的$result进行过滤,retun的内容会直接显示
    }
}

然后新建 文件frontend/controller/TestController.php

<?php
namespace frontend\controllers;
use yii\web\controller;
class TestController extends Controller {
    public function behaviors() {
        return [
            'test' => [
                'class' => 'frontend\libs\TestFilter'//调用过滤器
            ]
        ];
    }
    public function actionFilter() {
        return '当前action显示<br/>';//返回的内容会递交给过滤器,由afterAction进行处理
    }
}

最后,测试显示结果为:

在调用action前显示
当前action显示
在调用action后显示

过滤器完成。

 

2015年10月27日
发表者 will
暂无评论

Yii2自定义component应用组件开发

Yii2的配置文件中有一段component,很多重要配置都在这一段中完成。component中的设置作用是全局加载重要的类库,完成应用的基础功能,比如连接数据库、配置缓存、选择网站地区和语言、配置路由等等。自己写一个测试组件,有助于加深对component的了解。

这本次学习中,我把测试组件放到了frontend/libs文件夹下,命名为testcomponent.php。

<?php
namespace frontend\libs;
use yii\base\Component;
/**
 * 测试应用组件
 * 在main.php的component段中注册本组件后,应该可以随处用YII::$app->testcomponent进行调用
 */
class Testcomponent extends Component{
    public $param1;//测试参数1
    public $param2;//测试参数2
    public function test(){
        $string='Test component done!<br/>';
        $string.='param1="'.$this->param1.'"<br/>';
        $string.='param2="'.$this->param2.'"<br/>';
        return $string;
    }
}

然后,在main.php的component段中调用它。

        'testcomponent'=>[
            'class'=>'frontend\libs\testcomponent',//加载类库
            'param1'=>111,//设置参数
            'param2'=>222
        ]

接下来,新建一个testController进行测试:

namespace frontend\controllers;
use Yii;
use yii\web\Controller;
use frontend\lib\testcomponent;
/**
 * 测试
 */
class TestController extends Controller
{
    /**
     * 测试自定义组件
     */
    public function actionComponent(){
        //测试是否调用成功
        $t=YII::$app->testcomponent;
        echo $t->test();
        //测试能否在action里直接调用
        $t2=new \frontend\libs\Testcomponent();
        echo $t2->test();
        exit;
    }
}

访问该网页看到显示如下:

Test component done!
param1="111"
param2="222"
Test component done!
param1=""
param2=""

第一段显示说明这个测试类在main.php配置文件中调用成功了,第二段显示说明它也能够在action里直接调用。一般来说,不要在配置文件里注册太多应用组件,应用组件就像全局变量,使用太多可能加大测试和维护的难度。 可以在需要时再创建本地组件。

2015年10月27日
发表者 will
暂无评论

yii2的urlManager配置

网址伪静态是一个非常常用的网站需求,Yii2可以非常简单地进行配置。

首先,在配置文件config/main.php的’components’ 段中,加入如下设置:

'urlManager'=>array(  
             'enablePrettyUrl' => true,  //对url进行美化 
             'showScriptName' => false,//隐藏index.php   
             'suffix' => '.html',//后缀
             'enableStrictParsing'=>FALSE,//不要求网址严格匹配,则不需要输入rules
             'rules' => []//网址匹配规则
),

然后,启用服务器的rewrite规则,比如apache服务器里,在网站根目录web文件夹里新建.htaccess文件,输入如下内容:

RewriteEngine on

RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1

注意这个文件仅对apache有效,并且apache必须启用rewrite模块。

这样,网址就自动优化了。

urlManager有以下可用参数:

[table id=1 /]

YII2的rules配置相对其它框架已经算简单了,但真要熟练应用也需要多多练手,或是啃一下yii/web/UrlRule类库的。一般来说,我们用到以下这几条就足够了:

'rules' => [
    // 为路由指定一个别名简化网址
    'reg' => 'user/register',

    // 加id参数,这里用到了一点点正则,\d+在正则中表示至少一位的纯数字
    'article/<id:\d+>' => 'article/view',
    //标准的控制器/方法显示
    '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
    //加id参数
    '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',

    // controller和action进行严格限制
    '<controller:(post|comment)>/<id:\d+>/<action:(create|update|delete)>'
        => '<controller>/<action>',

    // 包含了 HTTP 方法限定,用于restful风格的Web Server
    'DELETE <controller:\w+>/<id:\d+>' => '<controller>/delete',

    // 配置Web Server ,接收 *.cn09.com 域名的请求
    'http://<user:\w+>.cn09.com/<lang:\w+>/profile' => 'user/profile',
]

根据以上规则,如果有什么特殊需求,应该多少也能猜到。如果需要完全理解路由规则,可以阅读一下yii/web/UrlRule源码,如果有特殊需求,也可以根据源码新建一个自己规则类来进行处理。

2015年10月26日
发表者 will
暂无评论

yii2用actions方法实现外部action统一加载

YII2框架开发程序时,很多时候会遇到一些功能大致相同的方法,这时候,可以选择把这些方法统一写到外部以方便管理。

例如在yii2的演示包里siteController.php文件中就有一段:

    public function actions()
    {
        return [
            'error' => [
                'class' => 'yii\web\ErrorAction',
            ],//返回错误
            'captcha' => [
                'class' => 'yii\captcha\CaptchaAction',
                'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
            ],//返回验证
        ];
    }

在这段程序里,分别用到了error和captcha两个外部action,分别用来回显错误和校验图形验证码。我们可以在vendor/yiisoft/yii2里找到对应的程序文件。

类似的,Yii2共提供了如下action:

  1. InlineAction
  2. CaptchaAction
  3. CreateAction
  4. DeleteAction
  5. IndexAction
  6. OptionsAction
  7. UpdateAction
  8. ViewAction
  9. ErrorAction
  10. GenerateAction

仿造这些文件,我们也可以编写自己的外部action。

第一步:找到frontend/libs文件夹,新建 文件TestAction.php

自写义的外部action,可以放到任意位置,作为示例,我把它放到网站的frontend/libs里面。

第二步:在文件TestAction.php中输入代码:

仿照已有的action文件,在新建的TestAction.php文件中写入如下内容:

<?php
namespace frontend\libs;
use yii\base\Action;
class TestAction extends Action {
    public function run() {
        return $this->controller->render('test');
    }
}

第三步:在SiteController里调用testAction:

修改SiteController的function actions,加上以下代码中的高亮部分:

    public function actions()
    {
        return [
            'error' => [
                'class' => 'yii\web\ErrorAction',
            ],//返回错误
            'captcha' => [
                'class' => 'yii\captcha\CaptchaAction',
                'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
            ],//返回验证
            'test'=>[
                'class'=>'frontend\libs\TestAction',
            ]
        ];
    }

第四步:在views/site下添加test.php视图文件

在TestAction中我们调用了视图,所以,需要添加相应的视图文件。如果在多个不同的controller中用到TestAction,那么,可以为每个controller配置不同的视图。

<h1>TestAction</h1>
<p>这是TestAction演示页面!</p>

第五步:现在,TestAction已经完成了,我们可以输入网址预览一下:

testAction页面截图

testAction页面截图

接下来,我们可以试试为testAction添加参数:

第六步:修改TestAction.php,添加待输入的三个参数:

<?php
namespace frontend\libs;
use yii\base\Action;
class TestAction extends Action {
    public $param1=NULL;
    public $param2=NULL;
    public function run($get=NULL) {
        return $this->controller->render('test',[
            'get'=>$get,
            'param1'=>$this->param1,
            'param2'=>$this->param2
        ]);
    }
}

这段代码中需要配置三个参数,$get、$param1、$param2,其中$get是在url中传递的,例如按照我电脑上的配置,访问http://127.0.0.8/index.php?r=site%2Ftest&get=xxx,就会为$get赋值xxx。而$param1和$param2则是在controller中设置的。

第七步:修改SiteController的function actions,为$param1和$param2赋值

    public function actions()
    {
        return [
            'error' => [
                'class' => 'yii\web\ErrorAction',
            ],
            'captcha' => [
                'class' => 'yii\captcha\CaptchaAction',
                'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
            ],
            'test'=>[
                'class'=>'frontend\libs\TestAction',
                'param1'=>'参数一',
                'param2'=>'参数二',
            ]
        ];
    }

这样,$param1和$param2参数就传递过去了。

最后,配置视图views/site/test.php完成测试:

<h1>TestAction</h1>
<p>这是TestAction演示页面!</p>
<p>$get="<?=$get?>"</p>
<p>$param1="<?=$param1?>"</p>
<p>$param2="<?=$param2?>"</p>

按各人本地路径访问网址如:http://127.0.0.8/index.php?r=site%2Ftest&get=xxx

可看到显示结果:

testAction参数传递截图

testAction参数传递截图

至此,testAction就完成了。

THE END

 

 

2015年10月26日
发表者 will
暂无评论

win10系统无法记住Tenda无线AP的WIFI密码

这几天遇到一个奇怪的问题,家里的腾达无线AP,型号tenda A301,网线连接路由器建立AP热点,用win10系统连接上网,每次都要重新输入密码,也无法设置为自动连接。网上搜索也没能找到解决方法。

今天的管理后台看到这台设备的主ssid和次ssid的默认值是一样的,也就是说,本来应该是两个wifi网络,现在是重名的,于是灵光一现,把次ssid改了个名字,重启路由器后问题解决,win10系统终于能够记住wifi密码了。

2013年8月20日
发表者 will
暂无评论

LDAP安装与使用(一)

LDAP是轻量目录访问协议,英文全称是Lightweight Directory Access Protocol,一般都简称为LDAP。LDAP不是关系型结构而是树状结构的。我们可以把LDAP理解为一个电话簿,LDAP的优势在于:

1.LDAP的权限可以指定到每个元素,而关系型数据库只能指定到表;
2.LDAP 优化读取速度而牺牲写入速度,所以适合放置长期不变的数据如通讯录、员工档案等
安装LDAP:
在ubuntu下安装LDAP可以输入如下命令:
sudo apt-get install slapd ldap-util

 

然后按提示输入参数完成安装。
修改LDAP的配置文件:/etc/ldap/ldap.conf
插入两行:
BASE dc=example,dc=com
URI ldap://ldap.yoursite.com ldap://ldap-master.yoursite.com:666

 

要用PHP操作LDAP,还需要安装PHP的扩展:
sudo apt-get install php5-ldap

 

安装完成后,在测试PHP文件里录入命令:
$ds=ldap_connect("ldap.bijiw.com");
var_dump($ds);

 

会提示:
resource(2) of type (ldap link)

 

显然,我们已经安装成功了。
安装一下管理工具试试:
sudo apt-get install phpldapadmin

 

安装成功,显示界面如下:
phpLDAPadmin (1.2.2) -
 
 

2013年8月20日
发表者 will
暂无评论

基于FLASH的网站语音留言功能

今天用到了一个网站语音留言功能,用户可以在网上录音发布自己的留言,以避免打字的繁琐。

实现方案的名称是FlashWavRecorder,下载地址是:https://codeload.github.com/cykod/FlashWavRecorder/zip/master

它基于一个名为swfobject的FLASH控件,地址是:http://code.google.com/p/swfobject,方案本身的源码里面已经包含了这个控件,所以你无需再单独下载它。

采用这个方案,可以兼容IE/FIREWORKS/CHROME等桌面浏览器,但手机、平板等手持设备由于不支持FLASH无法使用本功能。

下载的压缩包中包含如下文件:

FlashWavRecorder文件结构

其中,index.html是示例的首页:

$(function() {
var appWidth = 24;//flash初始宽度
var appHeight = 24;//flash初始高度
var flashvars = {'event_handler': 'microphone_recorder_events', 'upload_image': 'images/upload.png'};//flash参数
var params = {};
var attributes = {'id': "recorderApp", 'name': "recorderApp"};
swfobject.embedSWF("/js/recorder.swf", "flashcontent", appWidth, appHeight, "11.0.0", "", flashvars, params, attributes);//加载flash
});

 



对flash进行设置一般是用不到的,不过有个参数决定了语音的清晰度和录音文件的大小:

Recorder.configure(5);//1语音最清晰,5录音文件最小

 



recorder.js里面,具体演示了如何调用flash的API,可以解决大多数常见问题。
如果还是需要更多定制,下载包中也包含了as源码,可以自行对其进行修改后重新编译swf文件。

2013年8月15日
发表者 will
暂无评论

给wordpress博文的头部header加上描述标签description

站长这么认真地写博客,写完之后总是希望更多人看到,而被访客发现的有效途径之一当然就是搜索引擎,于是我们就需要定制网页头部的description标签。可是,基本上所有的wordpress主题都没有提供这个功能,于是,站长只能自己做一个啦。

好在这个非常简单:

在后台外观-编辑里选择header.php;

找到里面的</head>标签;

在标签上方插入代码:

<?php if(is_single()): ?>
<meta name="description" content="<?php echo trim(str_replace('Continue reading &rarr;','',strip_tags(get_the_excerpt())));?>">
<?php endif;?>

然后,记得在后台开启摘要功能,每次发博文时记得填写摘要。

这样,以后的每篇博文头部,就都会用摘要做为desrciption显示了。

 

2013年7月3日
发表者 will
暂无评论

七-敏捷协作

定期安排会面时间

站立会议可以提高开会效率

每个人都应该只回答三个问题:昨天有什么收获、今天计划做哪些工作、面临哪些障碍

每日立会有很多好处

立会时间不应该超过30分钟,理想时间是10~15分钟

小型团队一周立会两到三次就可以了

要注意报告细节

架构师必须写代码

架构师必须参与编码工作

如果架构师时间不够,可以选择不太重要的、工作量较低部分

不允许任何人单独进行设计,特别是你自己

实行代码集体所有制

如果某个开发人员在某个领域及其精通,要尽量发挥其所长

代码集体所有制不表示可以随心所欲,到处破坏

开发人员不必了解项目的每个细节,但应该随时可以处理某个模块的代码

有些代码不适合集体所有制,比如需要对特定领域的知识进行了解,或是难度很高,人多反而误事

成为指导者

一个问题反复讲述多次,可以考虑记录笔记、写成文章、甚至是写成一本书

成为指导者是向团队投资的一个好方式

结对编程是一种高效指导的自然环境

要尽可能引导别人而不是直接报答案

为团队成员在寻求帮助前陷入某个问题的时间设置一个时限,推荐一个小时

允许大家自己想办法

用问题来回答问题,给别人自己解决的机会

如果对方确实没能解决,就告诉对方答案,并解释为什么是这样

准备好后再共享代码

要保证提交代码前是可运行的,已通过所有测试

有些代码控制系统可以区分提交和可公开访问两种代码权限

仍然应该频繁提交代码。

做代码复查

轮流复查别人的代码

结对编程

及时通报进展与问题

每日立会是很好的通报方式

要照顾受众的关注点

别花费太多时间在问题通报上

经常抬头看四周,而不是埋头工作