symfony 调用不同app的routing

http://www.symfony-project.org/blog/2009/02/17/cross-application-links

Posted in routing | Comments Off

symfony 中文等匹配 sfValidatorRegex()

new sfValidatorRegex(
array(
'pattern' => '/^[^\W]?[a-zA-Z0-9\x{4e00}-\x{9fa5}_\s]*[^\W]?$/u'),
array(
'invalid'=>'昵称包含限制字符,请使用中文、英文和数字',
)

以下为转的:
2E80~33FFh:中日韩符号区。收容康熙字典部首、中日韩辅助部首、注音符号、日本假名、韩文音符,中日韩的符号、标点、带圈或带括符文数字、月份,以及日本的假名组合、单位、年号、月份、日期、时间等。
3400~4DFFh:中日韩认同表意文字扩充A区,总计收容6,582个中日韩汉字。
4E00~9FFFh:中日韩认同表意文字区,总计收容20,902个中日韩汉字。
A000~A4FFh:彝族文字区,收容中国南方彝族文字和字根。
AC00~D7FFh:韩文拼音组合字区,收容以韩文音符拼成的文字。
F900~FAFFh:中日韩兼容表意文字区,总计收容302个中日韩汉字。
FB00~FFFDh:文字表现形式区,收容组合拉丁文字、希伯来文、阿拉伯文、中日韩直式标点、小符号、半角符号、全角符号等。
比如需要匹配所有中日韩非符号字符,那么正则表达式应该是^[\u3400-\u9FFF]+$
理论上没错, 可是我到msn.co.ko随便复制了个韩文下来, 发现根本不对, 诡异
再到msn.co.jp复制了个 ‘お ‘, 也不得行..
然后把范围扩大到^[\u2E80-\u9FFF]+$, 这样倒是都通过了, 这个应该就是匹配中日韩文字的正则表达式了, 包括我們臺灣省還在盲目使用的繁體中文
而关于中文的正则表达式, 应该是^[\u4E00-\u9FFF]+$, 和论坛里常被人提起的^[\u4E00-\u9FA5]+$很接近
需要注意的是论坛里说的 ^[\u4E00-\u9FA5]+$这是专门用于匹配简体中文的正则表达式, 实际上繁体字也在里面, 我用测试器测试了下 ‘中華人民共和國 ‘, 也通过了, 当然, ^[\u4E00-\u9FFF]+$也是一样的结果

Posted in symfony 知识 | Comments Off

symfony 1.4 embedForm 保存2次问题

When a form is embedded, the embedded model representation is saved twice: one via fromArray(), that automatically hydrates related components, and another time via saveEmbeddedForm.

使用embed会出现insert 2次的问题

configure(){
embedRelation('ForwardProfile');
}
function addProfile(){
//embed a new form
$profiles = new sfForm();
      $profile = new ForwardProfile();
      $profile->setForward($this->getObject());
      $profile_form = new ForwardProfileForm($profile);
      $profiles->embedForm('0',$profile_form);
      $this->embedForm('ForwardProfile',$profiles);
}
function bind(){
$this->addProfile();
}

这时会出现插入2条记录的情况,将关联名称‘ForwardProfile改为其它名字可以解决

....
function addProfile(){
//embed a new form
...
      $this->embedForm('Fp',$profiles);
}
....
Posted in forms | Comments Off

symfony Doctrine link 添加一对多关联记录

例子:

User(table)
————
id:~
——————
Book(table)
————
id:~
user_id(fk)
——————

添加一个user和他的藏书
1.

$u=new User();
$u->name = 'lag'
$u->save();
------------------
$b=new Book();
$b->name = 'lag book';
$b->save();
$b->link('User',array($u['id']));

2.

$u=new User();
$u->name = 'lag';
$u->Book[]->name = 'lag book';
$u->save();

3.

$bookids = array();
$b1= new Book();
$b1->name = 'book1';
$b1->save();
$bookids[]=$b1['id'];

$b2= new Book();
$b2->name = 'book2';
$b2->save();
$bookids[]=$b2['id'];

$u=new User();
$u->name = 'lag'
$u->save();

$u->link('Book',$bookids);
Posted in Doctrine | Comments Off

symfony 关联id必须unset才会自动添加

数据库结构2个表:
user
----------
id
name
----------

book
----------
id
user_id(fk)
name
----------

bookForm.class.php的configure()设置

unset($this['user_id']);

这样embedForm后,user_id值自动添加为user的id值

Posted in forms | Comments Off

symfony 1.4 Doctrine formArray()数组作为表单保存

formArray()可以将一组数据作为form表单保存

$data = array(
'name' => 'John',
'age' => '25',
'Emails' => array(
array('address' => 'john@mail.com'),
array('address' => 'john@work.com')
);
$user = new User();
$user->fromArray($data);
$user->save();
Posted in Doctrine | Leave a comment

symfony 1.4 Doctrine toArray()

object->toArray($deep)
$deep为true时,将关联数据也转换为数组

$user = $q->leftJoin('Books')->where(...)->fetchOne();
$user->toArray(true)

echo $user['name']
echo $user['Books']['id']
Posted in Doctrine, Uncategorized | Leave a comment

symfony 1.4 Doctrine fetchOne返回数组

fetchOne($params,$hydrationMode);默认返回为对象,返回数组使用Doctrine::HYDRATE_ARRAY

$user = $q->where('id=?')
  ->fetchOne(array(1))
  ->toArray();

等同于:
$user = $q->where('id=?')
  ->fetchOne(array(1),Doctrine::HYDRATE_ARRAY);
等同于:
$user = $q->where('id=?',array(1))
  ->setHydrationMode(Doctrine::HYDRATE_ARRAY)
  ->fetchoOne();

							
Posted in Doctrine, Uncategorized | Leave a comment

添加多条记录,字段为空则不添加(bind)

目的:
用户自定义数目的记录,有内容的input则插入数据库,没内容则忽略
例子:
1

已经embed的字段要用unset()才不会插入数据库

/lib/.../xxForm.class.php
...
public function addNewTargets($number) {
        $targets = new sfForm();
        for($i=0;$i<$number;$i++) {
            $target = new WeightTarget();
            $target->setWeightWatcher($this->getObject());
            $target_from = new WeightTargetForm($target);
            $targets->embedForm($i, $target_from);
        }
        $this->embedForm('new', $targets);
    }
  public function bind(array $taintedValues = null, array $taintedFiles = null){
    $new_targets = new sfForm();
    $taintedValues['user_simple_id'] = sfContext::getInstance()->getUser()->getGuardUser()->getId();
    foreach($taintedValues['new'] as $key => $new_target){

      if(!empty ($new_target['title'])){
          $target = new WeightTarget();
          $target->setWeightWatcher($this->getObject());
          $target_form = new WeightTargetForm($target);
          $new_targets->embedForm($key,$target_form);
      }else{ //字段为空则unset()
          unset ($taintedValues['new'][$key]);
      }
    }

    $this->embedForm('new',$new_targets);
    }
    parent::bind($taintedValues, $taintedFiles);
  }

#.apps/.../actions.class.php
public function executeNew(sfWebRequest $request)
  {
    $this->number = 5;#显示5条执行事项
    $this->form = new WeightWatcherForm();
    $this->form->addNewTargets($this->number);
  }
#template
...
<?php include_partial('addTargets', array('form'=>$form,'number'=>$number))?>
...

 

#partial
<?php for($i=0;$i<$number;$i++):?>
<tr>
    <th scope=”row”><?php if($i<9) echo ’0′.($i+1); else echo $i+1;?>.</th>
    <td>
        <?php echo $form['new'][$i]['title']->render(array(‘class’=>’target_list’))?>
    </td>
</tr>
<?php endfor;?>

如果提交create时发现有非法字段,我们会发现提示错误。因为现在的记录数已经不是5条。所以我们要重新设置记录数:

...
public function executeCreate(sfWebRequest $request)
  {
$post = $request->getPostParameters();

    $this->number = count($post['weight_watcher']['new']);#显示5条执行事项
    $this->form = new WeightWatcherForm();
    $this->form->addNewTargets($this->number);
...
}
...

就ok了。

Posted in Uncategorized, forms | Leave a comment

Embedded forms with symfony 1.4 and jQuery

http://tech.cibul.org/embedded-forms-with-symfony-1-4-and-jquery/

How to implement a single interface to insert multiple entries linked by one-to-many relations…

I’ve been looking recently for a way to build a form that would allow the input of data (edition or adding new data) into multiple related objects. Turns out the way to do this in symfony is to use embedded forms and this what this post is about. I am not an expert in symfony nor in jQuery so if find better ways to do some of the things described here I’ll be happy to read your comments.

We’ll build a listing of events which will be editable to the user. Each event has one or more occurrences (a place and a time). Forms shown should allow the user to edit each event and their related occurrences under the same interface plus leaving them the possibility to add new occurrences if needed.

We will do this in 5 steps:

  1. Setting up the project: we’ll create a symfony project and mysql database
  2. Editing Events: we’ll create a form where both events and occurrences can be edited using embedded forms
  3. Adding new occurrence fields: we’ll add the functionality to add more blank occurrence fields using jQuery Ajax functions
  4. Removing new occurrence fields: still using jQuery, we’ll allow the user to remove blank occurrence fields
  5. Creating a new Event: We’ll modify the form template slightly to allow the user to add more events to the list

Ok, this should take a little while so let’s get started!

1. Setting up the project and showing the index page

We start by setting up a symfony project and building a database based on the following schema and fixtures:

The schema:

#config/doctrine/schema.yml
Event:
 columns:
   id:
     type: integer
     primary: true
     autoincrement: true
   title:
     type: string(255)
     notnull: true
 relations:
   Occurrences:
     type: many
     class: Occurrence
     local: id
     foreign: event_id
     onDelete: CASCADE

Occurrence:
 columns:
   id:
     type: integer
     primary: true
     autoincrement: true
   location:
     type: string(255)
     notnull: true
   date:
     type: date
     notnull: true
   event_id:
     type: integer
     notnull: true
 relations:
   Event:
     type: one
     local: event_id

… and the fixtures:

#data/fixtures/fixtures.yml
Event:
 apero_geant:
   title: Apero Geant
 rugby_night:
   title: Rugby Night

Occurrence:
 apero_geant1:
   Event: apero_geant
   location: Marseille, France
   date: ‘2009-08-29
 apero_geant2:
   Event: apero_geant
   location: Nantes, France
   date: ‘2009-11-10
 apero_geant3:
   Event: apero_geant
   location: Rennes, France
   date: ‘2010-03-25
 rugby_night1:
   Event: rugby_night
   location: Yvetot, France
   date: ‘2010-03-20

After generating a frontend app, we can create an ‘event’ module by just adding the event/actions and event/templates directories under the modules directory of the app.

In an action.class.php file, we create a first index action that sends a list of events to an indexSuccess.php template.

<?php // apps/frontend/modules/event/actions/actions.class.php

  class eventActions extends sfActions{

    public function executeIndex(sfWebRequest $request){
      $this->events = Doctrine_Core::getTable(‘Event’)->findAll();
    }

  }

To make things simple, we’ll set the index action as default in the routing, removing the default content.

#app/frontend/config/routing.yml
homepage:
 url:   /
 param: { module: event, action: index }

The occurrences are listed under each event in the indexSuccess.php template:

<!–apps/frontend/modules/templates/indexSuccess.php –>
<h2>Events Index</h2>
<?php foreach($events as $event): ?>
<div class=”event-item”>
  <h3><?php echo $event->getTitle() ?></h3>
  <ul>
    <?php foreach($event->getOccurrences() as $occurrence): ?>
      <li><?php echo $occurrence->getDate()?><?php echo $occurrence->getLocation() ?></li>
    <?php endforeach;?>
  </ul>
</div>
<?php endforeach; ?>

There, the first step is done and the project is set up with a default index page showing the events and their occurrences

2 – Editing existing events & their occurrences

Now we have to setup the embedded form structure

We want to be able to edit any of the listed events and their occurrences in the same form. Let’s start by creating an edit action and associated template and link it to the index page. We’ll start simple and setup a standard form that will allow us to update the title field of the event. Once this is running we will start working with embedded forms to add the possibility to edit the related occurrences as well.

To get things working we need to create an edit action and template to launch the edition form, a submit action for updating the database when the form has been filled, and we’ll add some links to the index page to be able to access the edit menu for each event.

  • Let’s start with the executeEdit() action: It simply creates a form and sends it to the editSuccess.php template
    // apps/frontend/modules/event/actions/actions.class.php

        public function executeEdit(sfWebRequest $request){
          $this->forward404Unless($event = Doctrine::getTable(‘Event’)->find(array($request->getParameter(‘id’))), sprintf(‘Event does not exist (%s).’, $request->getParameter(‘id’)));
          $this->form = new EventForm($event);
        }

  • The template editSuccess(): It lays out the form and has it ready to send the result to the submit action
    <!–apps/frontend/modules/templates/editSuccess.php–>
    <h2>Edit Event</h2>

    <form action=”<?php echo url_for(‘@submit’) ?>” method=”post”>
      <?php echo $form->renderHiddenFields() ?>
      <?php echo $form['title']->renderLabel()?> <?php echo $form['title']->renderError()?> <?php echo $form['title'] ?>
      <input type=”submit” value=”Save” />
    </form>

    <a href=”<?php echo url_for(‘@homepage’)?>“>Back to index</a>

  • The routing has to be updated with both edit and submit routes:
    #app/frontend/config/routing.yml
    edit:
     url: /edit
     param: { module: event, action: edit }

    submit:
     url: /submit
     param: { module: event, action: submit }

  • And the submit action, executeSubmit(): it extracts from the request the values passed on by the form, gets the event object based on the extracted id, makes a form from it, binds it with the request data and updates the database. It is important here to focus on what binding a form means: basically, when the form is created from an event object generated from the database, the values stored are the ones of the database, not the ones input by the user in the previous page; these are still stored in the request object. The bind action consists in taking the values of the request and using them to update the freshly created form, checking the validity of the data in the process, as per the form’s rules. If the validity is confirmed, the database is updated by the save method.
    // apps/frontend/modules/event/actions/actions.class.php

        public function executeSubmit(sfWebRequest $request){
          $tainted_values = $request->getParameter(‘event’);
          $event = Doctrine::getTable(‘Event’)->find($tainted_values['id']);

          $this->form = new EventForm($event);

          if ($request->isMethod(‘post’) && $this->form->bindAndSave($tainted_values))
            $this->redirect(‘@homepage’);

          $this->setTemplate(‘edit’);
        }

  • The index should have link for each event to allow users to show the edit page, add this under the event title:
    <!–apps/frontend/modules/templates/indexSuccess.php –>

    <a href=”<?php echo url_for(‘event/edit?id=’.$event->getId())?>“>edit event</a>

    Now you should have a straightforward way of updating event titles. But here comes the tricky part: how to updated the data of the occurrences of the event as well? This can actually be done easily by fiddling with the event form and embedding occurrence forms to it. But we only want to embed the occurrences which are linked to the event. A method serves that purpose and can be used to do just that in one line: embedRelation(). This method basically takes all related objects and generates the corresponding embedded forms. Enough bla bla, lets update the EventForm class with it:

    <?php //lib/form/doctrine/EventForm.class.php

    class EventForm extends BaseEventForm
    {
      public function configure()
      {
        $this->embedRelation(‘Occurrences’);
      }
    }

    Open the OccurrenceForm.class.php and unset the variables that should’nt be in the form:

    <?php //lib/form/doctrine/OccurrenceForm.class.php

    class OccurrenceForm extends BaseOccurrenceForm
    {
      public function configure()
      {
        unset($this['event_id']);
      }
    }

    Now update as well the editSuccess.php template to show the occurrences of an event when they exist… add this bit under the event title fields:

    <!–apps/frontend/modules/templates/editSuccess.php–>
    <ul>
        <?php foreach ($form['Occurrences'] as $occurrence):?>
        <li>
          <?php echo $occurrence['date']->renderLabel() ?>  <?php echo $occurrence['date']->renderError() ?>
          <?php echo $occurrence['date'] ?>
           -
          <?php echo $occurrence['location']->renderLabel() ?>  <?php echo $occurrence['location']->renderError() ?>
          <?php echo $occurrence['location'] ?>
        </li>
        <?php endforeach ?>
      </ul>

    There. Your form allows you to update the occurrences as well.

    3 – Adding new occurrence field sets with jQuery

    But what if you want to add new occurrences to your event? Wouldn’t it be swell to have some neat way to add new occurrence fields as you please now wouldn’t it?

    Sure it would. And we’ll make it happen using some ajax functions with jQuery.

    To do this, we’ll add some javascript mechanisms on the edition page that will consist in querying the server for some bits of forms, and once receive, appending them to the rest of the page without the need for a refresh. On the server side, a new action will handle the ajax request and re-assemble the forms to send the right piece back.

    We start by adding the jquery library (I’m using jquery 1.4.2) to the js folder as well as an empty js file (eventform.js). In the layout.php of the frontend app we add a reference to each file in the header

    <!–app/frontend/template/layout.php–>

        <?php include_stylesheets() ?>
        <?php use_javascript(‘jquery-1.4.2.min.js’) ?>
        <?php use_javascript(‘eventform.js’) ?>
        <?php include_javascripts() ?>

    Now in the editSuccess.php templage, we’ll add a button (a link actually) after the occurrence list. We’ll bind it with javascript behavior to add the new fields.

    <!–apps/frontend/modules/templates/editSuccess.php–>

    </ul>
    <a id=“addoccurrence” href=“#”>Add an occurrence</a>

    In the javascript file (eventform.js), add the following:

    /* web/js/eventform.js */
    newfieldscount = 0;

    function addNewField(num){
      return $.ajax({
        type: ‘GET’,
        url: ‘/add?num=’+num,
        async: false
      }).responseText;
    }

    $(document).ready(function(){
      $(‘#addoccurrence’).click(function(e){
        e.preventDefault();
        $(‘ul’).append(addNewField(newfieldscount));
        newfieldscount = newfieldscount + 1;
      });
    });

    Everytime the page element with #addoccurrence as id will be clicked, a new field will be fetched through an ajax request and be appended to the occurrence list. The missing piece now is the processing on the server side of the request. First thing is to update the routing by adding the route we describe in the javascript file…

    #app/frontend/config/routing.yml
    add:
     url: /add
     param: { module: event, action: add }

    … and add the corresponding action, which should work only when the request comes from an XmlHttpRequest.

    // apps/frontend/modules/event/actions/actions.class.php

        public function executeAdd(sfWebRequest $request){
          $this->forward404unless($request->isXmlHttpRequest());
          $number = intval($request->getParameter(“num”));

          $this->form = new EventForm();

          $this->form->addNewFields($number);

          return $this->renderPartial(‘addNew’,array(‘form’ => $this->form, ‘number’ => $number));
        }

    The action calls a method of the EventForm class that will add the number of occurrences needed to replicate the current structure of the form displayed.

    //lib/form/doctrine/EventForm.class.php

      public function addNewFields($number){
        $new_occurrences = new BaseForm();

        for($i=0; $i <= $number; $i+=1){
          $occurrence = new Occurrence();
          $occurrence->setEvent($this->getObject());
          $occurrence_form = new OccurrenceForm($occurrence);

          $new_occurrences->embedForm($i,$occurrence_form);
        }

        $this->embedForm(‘new’, $new_occurrences);
      }

    As you can see, Forms behave as arrays. When you need to create a form with multiple embedded forms, you first create an array of form and you embed in it all the forms that you need. Once you’re done, you embedd that form array into your main form.

    Now we need to create the partial that contains the html to send back to the ajax call. It should contain only the last embedded form (the one to be added).

    //apps/frontend/modules/event/templates/_addNew.php
    <li>
      <?php echo $form['new'][$number]['date']->renderLabel() ?>  <?php echo $form['new'][$number]['date']->renderError() ?>
      <?php echo $form['new'][$number]['date'] ?>
       -
      <?php echo $form['new'][$number]['location']->renderLabel() ?>  <?php echo $form['new'][$number]['location']->renderError() ?>
      <?php echo $form['new'][$number]['location'] ?>
    </li>

    One last thing: now, when the event form is submitted and received by the submit action, the action creates a form to which the data in the request will be bound (the data you just submitted). But before this can happen, the structure of the form needs to match the data received: the number of new embedded forms should be the same as the number submitted. The bind method in the EventForm does just that: it recreates the structure of the request data in the created form before the form binding is done.

    //lib/form/doctrine/EventForm.class.php

      public function bind(array $taintedValues = null, array $taintedFiles = null){

        $new_occurrences = new BaseForm();
        foreach($taintedValues['new'] as $key => $new_occurrence){
          $occurrence = new Occurrence();
          $occurrence->setEvent($this->getObject());
          $occurrence_form = new OccurrenceForm($occurrence);

          $new_occurrences->embedForm($key,$occurrence_form);
        }

        $this->embedForm(‘new’,$new_occurrences);

        parent::bind($taintedValues, $taintedFiles);
      }

    4 – Removing new occurrence field sets with jQuery

    What about removing added empty occurrences? This is less tricky as it does not require any server side processing. All we will need to do now is add a remove link for each of the new occurrence fields and add behavior to them.

    First things first, the remove link has to be added in the addNew.php partial:

    <!–apps/frontend/modules/event/templates/_addNew.php–>

    <a class=“removenew” href=“#”>Remove</a>
    </li>

    Now some behavior needs to be bound to it. One small thing: as this link is loaded through javascript, the behavior needs to be loaded after the item has been loaded.

    We have to update the eventform.js with a removeNew function which will be launched everytime the remove button is pressed.

    /* web/js/eventform.js */

    var removeNew = function(){
      $(‘.removenew’).click(function(e){
        e.preventDefault();
        $(this).parent().remove();
      })
    };

    Still in the javascript file, update the #addoccurrence button behavior:

    /* web/js/eventform.js */

    $(document).ready(function(){
      $(‘#addoccurrence’).click(function(e){
        e.preventDefault();
        $(‘ul’).append(addNewField(newfieldscount));
        newfieldscount = newfieldscount + 1;
        $(‘.removenew’).unbind(‘click’);
        removeNew();
      });
    });

    Et Voila.

    5 – Adding new events

    Now one last thing we want to do: add a link to the index page to display a form for adding new events. When a new event is created, it should at least contain one occurrence. This should be simple: we will re-use the indexSuccess.php template by modifying it slightly and add a new action.

    We can create the link in the index page (at the end):

    <!–apps/frontend/modules/templates/indexSuccess.php –>

    <a href=”<?php echo url_for(‘@new’)?>“>Add an Event</a>

    Update the routing.

    #app/frontend/config/routing.yml
    new:
     url: /new
     param: { module: event, action: new }

    … and create the executeNew action

        public function executeNew(sfWebRequest $request){
          $event = new Event();
          $this->form = new EventForm($event);

          $this->form->addNewFields(0);

          $this->setTemplate(‘edit’);
        }

    … and as well update the editSuccess.php template so that one new field is readily available (and non removable) when the form is for a new event. Add this just after the ul tag:

    <!–apps/frontend/modules/templates/editSuccess.php–>
        <?php if ($form->getObject()->isNew()): ?>
        <script type=”text/javascript”>newfieldscount = 1;</script>
          <li>
            <?php echo $form['new'][0]['date']->renderLabel() ?>  <?php echo $form['new'][0]['date']->renderError() ?>
            <?php echo $form['new'][0]['date'] ?>
             -
            <?php echo $form['new'][0]['location']->renderLabel() ?>  <?php echo $form['new'][0]['location']->renderError() ?>
            <?php echo $form['new'][0]['location'] ?>
          </li>
        <?php endif ?>

    I’ll leave you to do something similar with the title to replace “Edit Event” with “New Event”

    And we’re done! This should allow you to edit and add events and their occurrences, using embedded forms and dynamic functions to add more occurrences. I hope this will be useful for you. Again, your input and comments are welcome.

    By the way, you can download the code here.

    Thanks to Nacho and Nicolas, their posts were very useful. You can find find another interesting tutorial on embedded forms here.

Posted in Uncategorized, forms | Leave a comment

生意人的素质标准[转]

我首先要说明的是做生意赚钱与做事业是两回事,我这里只说做小生意,就是普通人开个店、做个经销商、开个小贸易公司、白领辞职后开个小咨询公司等普通中国人的小生意; Continue reading

Posted in Uncategorized | Leave a comment

支持symfony框架的IDE NetBeans

支持symfony框架的IDE NetBeans

Posted in symfony 知识 | Leave a comment

nginx日志分析解决方案

- Awstats 很多PHP搭建的网站都在由apache转向了nginx。nginx的日志信息如何分析呢? 当然你可以自己写一个,但是这里也推荐一款结果信息非常详尽的开源工具——Awstats ,它基于perl编写,它的介绍如下:

AWStats is a free powerful and featureful tool that generates advanced web, streaming, ftp or mail server statistics, graphically. This log analyzer works as a CGI or from command line and shows you all possible information your log contains, in few graphical web pages. It uses a partial information file to be able to process large log files, often and quickly. It can analyze log files from all major server tools like Apache log files (NCSA combined/XLF/ELF log format or common/CLF log format), WebStar, IIS (W3C log format) and a lot of other web, proxy, wap, streaming servers, mail servers and some ftp servers.

点击这里去官方网站

第一步,日志的处理。

最好每天分割一下日志,一开始没注意这个工作,结果不久日志文件就上G了,很痛苦。分割日志很简单,首先把日志文件复制到别的地方,然后再通知nginx重新生成日志就可以了。shell脚本如下:

#!/bin/bash

logs_path=”/nginx/logs/”
mv ${logs_path}access.log ${logs_path}access_$(date -d “yesterday” +”%Y%m%d”).log
kill -USR1 `cat /nginx/logs/nginx.pid`

代码中的/nginx/logs指的是nginx的log日志文件所在目录,生成了以昨天日期命名的日志文件。

为了达到每天自动分割的目的,在crontab中加入以下部分:

1 0 * * * sh /home/zyf/sh/cut_nginx_log.sh
这样就每天的0点1分把nginx日志重命名为日期格式,并重新生成今天的新日志文件。

第二步,Awstats的配置。

日志文件分割好了,接下来就是分析了,也就是Awstats的使用了。
Awstats的配置文件默认会存储在/etc/awstats/目录下,包括你安装时设置的域名如:awstats.www.xxxxke.com.conf。在这个配置文件中修改这个地方:
LogFile=”/nginx/logs/access_%YYYY-0%MM-0%DD-24.log”
这个意思是要去读取nginx昨天的日志文件,关于后边%YYYY-0%MM-0%DD-24的设置,规则如下:

# You can also use tags in this filename if you need a dynamic file name
# depending on date or time (Replacement is made by AWStats at the beginning
# of its execution). This is available tags :
# %YYYY-n is replaced with 4 digits year we were n hours ago
# %YY-n is replaced with 2 digits year we were n hours ago
# %MM-n is replaced with 2 digits month we were n hours ago
# %MO-n is replaced with 3 letters month we were n hours ago
# %DD-n is replaced with day we were n hours ago
# %HH-n is replaced with hour we were n hours ago
# %NS-n is replaced with number of seconds at 00:00 since 1970
# %WM-n is replaced with the week number in month (1-5)
# %Wm-n is replaced with the week number in month (0-4)
# %WY-n is replaced with the week number in year (01-52)
# %Wy-n is replaced with the week number in year (00-51)
# %DW-n is replaced with the day number in week (1-7, 1=sunday)
# use n=24 if you need (1-7, 1=monday)
# %Dw-n is replaced with the day number in week (0-6, 0=sunday)
# use n=24 if you need (0-6, 0=monday)
# Use 0 for n if you need current year, month, day, hour

第三步,开始分析、生成结果。

最后,可以执行分析了。使用这个命令:
/usr/local/awstats/wwwroot/cgi-bin/awstats.pl -update -config=www.xxxxke.com

这个命令会把结果生成到/var/lib/awstats 目录下 awstatsXXXX.www.XXXX.com.txt文件。

当然啦,这样看起来不太方便哦,呵呵,可以再用下面的命令来生成html页面,相当漂亮:

perl /usr/local/awstats/tools/awstats_buildstaticpages.pl -update \
-config=www.xxxxoke.com -lang=cn \
-dir=/html/awstats \
-awstatsprog=/usr/local/awstats/wwwroot/cgi-bin/awstats.pl

这样就会在/html/awstats目录下生成很漂漂的分析结果页,很暴力很强大。

第四步,自动化。

要是每天都去服务器上运行几条命令肯定是件令人烦燥的事情,所以呢,linux的世界里有crontab这样的好东东,很简单,下面是我的crontab

1 0 * * * sh /home/zyf/sh/cut_nginx_log.sh

0 1 * * * /usr/local/awstats/wwwroot/cgi-bin/awstats.pl -update -config=www.xxxxke.com

0 2 * * * perl /usr/local/awstats/tools/awstats_buildstaticpages.pl -update -config=www.xxxxke.com -lang=cn -dir=/html/awstats -awstatsprog=/usr/local/awstats/wwwroot/cgi-bin/awstats.pl

————————————————————————-

大功告成,打完收功……

Posted in Uncategorized | Leave a comment

cygwin安装

http://www.programarts.com/cfree_ch/doc/help/UsingCF/CompilerSupport/Cygwin/Cygwin1.htm

http://www.cygwin.com/

http://www.cygwin.cn/

Posted in Server | Comments Off

symfony上传文件

symfony 1.2 利用form类,设置文件上传。

class WorldImagesForm extends BaseWorldImagesForm
{
  public function configure()
  {
  	$this->widgetSchema['file'] = new sfWidgetFormInputFile();
  	$this->validatorSchema['file'] = new sfValidatorFile(array(
  	'required' => false,
  	'path' => sfConfig::get('sf_upload_dir').'/images/guide',
  	'max_size' => '5242880',
  	'mime_types' => 'web_images'),
  	array(
  	'max_size' => '最大15Mb!',
  	'mime_types' => '只支持web图片格式'
  	));

  }
}
Posted in forms | Leave a comment

mysql 查询一条记录的上一条和下一条记录

EG:查询表content 中id是3的上一条和下一条记录,注意:ID是Int

SELECT * FROM content WHERE id IN (SELECT CASE WHEN SIGN(id – 3) > 0 THEN MIN(id) WHEN SIGN(id – 3) < 0 THEN MAX(id) END AS id
FROM content WHERE id <> 3 GROUP BY SIGN(id – 3) ORDER BY SIGN(id – 3)) ORDER BY id ASC;
mysql 查询一条记录的上一条和下一条记录

Posted in mysql | Leave a comment

mysql获得最后一条记录

select id from article where id= (select max(id) from article);
mysql获得最后一条记录

Posted in mysql | Leave a comment

symfony1.2数据库保存session

创建数据表sessions Continue reading

Posted in Propel | Leave a comment

图片验证扩展sfValidatorFileImage

http://snippets.symfony-project.org/snippet/343

Posted in symfony 知识 | Leave a comment

缩略图插件sfThumbnailPlugin

http://www.symfony-project.org/plugins/sfThumbnailPlugin

Posted in symfony 插件 | Leave a comment