每次在db表中插入一条记录时,更新CakePhp View [英] Update CakePhp View each time a record is inserted in the db table

查看:115
本文介绍了每次在db表中插入一条记录时,更新CakePhp View的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Am开发的应用程序将允许通过浏览器远程查看记录和报告.我使用cakePHP使应用程序及其工作正常,但是我有一个小问题,因为该应用程序不执行任何插入操作,只是读取数据,我希望在用户打开视图并插入记录时在表中,它应该更新所有打开的客户端,而不是用户刷新页面以获取新记录. 是否有一个CakePHP Websocket插件真正起作用? 我们的网络主机不允许安装程序或添加apache模块,因此nodejs或类似的解决方案将不适用于此处.

Am making an application that will enable remote viewing of records and reports via a browser. I have used cakePHP to make the application and its working fine,but i have one little problem,since the application does not do any inserts its just reading the data,i want when a user has opened a view and a record has been inserted on the table,it should update all open clients, instead of the user refreshing the page to get the new records. Is there a cakePHP websocket plugin that actually works? Our webhost doesnt allow installing programs or adding apache modules so nodejs or similar solutions wont be applicable here.

我正在寻找一个纯粹的php和javascript实现, 只需将您的应用程序文件上传到网络服务器,一切 运行.上传文件后,您无需运行,安装额外功能或对apache或东西进行任何配置.

Am looking for a purely php and javascript implementation where you just upload your application files to the webserver and everything runs. You dont have to run, install extras or do any configuration on apache or stuff... afteruploading your files

这是我的一个控制器(BooksController.php)中的一个函数,用于将数据检索到视图中

here is a function in one of my controllers(BooksController.php) that retrieves the data to the view

public function list_books()
  {
    $this->Books->recursive = 0;
    $this->paginate = array('order' => array('Serial_No' => 'DESC'));
    $this->set('All_Books', $this->paginate());
  }

这是我的其中一个视图(list_books.ctp),它在分页的表中显示数据.

and here is one of my views(list_books.ctp) that displays the data in a table paginated.

<div class="row-fluid">

    <div class="span12">
        <?php echo $this->Session->flash() ?>   
        <h4><?php echo __('All Books') ?></h4>
        <hr>               
                    <table class="table table-bordered">
            <thead>
                <tr>    <th><?php echo __('Serial No') ?></th>
                    <th><?php echo __('Title') ?></th>
                                        <th><?php echo __('Author') ?></th>
                                        <th><?php echo __('Publisher') ?></th>
                                        <th><?php echo __('Category') ?></th>
                                        <th><?php echo __('Section') ?></th>
                                        <th><?php echo __('Available') ?></th>
                </tr>
            </thead>
            <tbody>
                <?php foreach( $All_Books as $book ){ ?>
                <tr>
                    <td><?php echo $this->Html->link(__($book['Book']['Serial_No']),'/books/view/'.$book['Book']['Serial_No']) ?></td>                                         
                                        <td><?php echo $book['Book']['Title'] ?></td>
                                        <td><?php echo $book['Book']['Author'] ?></td>
                                        <td><?php echo $book['Book']['Publisher'] ?></td>
                                        <td><?php echo $book['Book']['Category'] ?></td>
                                        <td><?php echo $book['Book']['Section'] ?></td>
                                        <td><?php echo $book['Book']['Available'] ?></td>
                </tr>
                <?php } ?>
            </tbody>
        </table>
                <?php echo $this->Paginator->prev('« Previous', null, null, array('class' => 'disabled'));            
echo $this->Paginator->numbers();
echo $this->Paginator->next('Next »', null, null, array('class' => 'disabled'));
echo $this->Paginator->counter(array(
    'format' => 'Page {:page} of {:pages}, showing {:current} records out of
             {:count} total, starting on record {:start}, ending on {:end}'
));
 ?>
    </div>

</div>

我可以在视图,控制器或模型上添加什么以使视图自动更新? 可以使用ajax来实现吗?

What can i add on my view or controller or model, to make the view auto updating? Can this be achieved using ajax?

推荐答案

您已经提到AJAX.这是完成类似操作的最简单方法,只需通过AJAX在后台进行检查,然后在必要时重新加载页面,或再次使用AJAX请求仅更新受影响的部分.

You've already mentioned it, AJAX. That's the easiest way to accomplish something like that, simply do a check in the background via AJAX, and if necessary reload the page, or update only the affected parts by again using an AJAX request.

根据数据量,您当然可以直接加载数据,而不用先检查更新.

Depending on the amount of data you could of course simply load the data directly instead of checking for updates first.

更新我误解了这个问题,如果插入件/附加件是由注释中所述的您无法直接控制的外部来源制作的,那是我想到的唯一选择用于检查是否需要更新视图,将检查UPDATE_TIME 信息模式(仅适用于MyISAM),使用触发器,用于更新可以检查的自定义信息模式或对行进行计数,但是行仅覆盖插入.

Update I've misunderstood the question, in case the inserts/udpates are made from an external source that you have no direct control over as described in the comments, the only options I could think of for checking whether updating the view is necessary, would be checking the UPDATE_TIME information schema (works on MyISAM only), using triggers for updating a custom information schema that could be checked, or counting the rows, however the latter would only cover inserts.

所有方法都将在特定视图的控制器操作中获取比较值(更新时间或行数),并将该值传递给随后在AJAX调用中使用的视图. AJAX调用调用一个控制器方法,该方法将传递的值与当前时间/计数值进行比较,以确定是否有必要进行更新.

All methods would fetch the comparison value (update time or row count) in the controller action of the specific view, and pass that value to the view where it's then used in the AJAX call. The AJAX call invokes a controller method where the passed value is compared to the current time/count value in order to determine whether an update is necessary.

请注意,这些示例未经测试!

Please note that the examples are untested!

最简单的方法是检查UPDATE_TIME信息模式,但是如上所述,这仅适用于MyISAM表:

The easiest method would be checking the UPDATE_TIME information schema, however as mentioned this only works for MyISAM tables:

型号:

public function getUpdateTime()
{   
    $db = $this->getDataSource();

    $result = $db->fetchAll('
        SELECT
            UNIX_TIMESTAMP(UPDATE_TIME) AS update_time
        FROM
            information_schema.tables
        WHERE
            TABLE_SCHEMA = ?
            AND
            TABLE_NAME = ?',

        array
        (
            $db->config['database'],
            $this->table
        )
    );

    if(empty($result) || !isset($result[0][0]['update_time']))
    {
        return false;
    }

    return (int)$result[0][0]['update_time'];
}

控制器:

public function list_books()
{
    $this->set('lastUpdate', $this->Books->getUpdateTime());

    $this->Books->recursive = 0;
    $this->paginate = array('order' => array('Serial_No' => 'DESC'));
    $this->set('All_Books', $this->paginate());
}

public function checkForUpdate($time)
{
    $updateNecessary = $this->Books->getUpdateTime() > (int)$time;
    return new CakeResponse(array('body' => json_encode($updateNecessary)));
}

查看:

<script>
jQuery(function($)
{
    var lastUpdate = <?php echo $lastUpdate; ?>;

    function checkForUpdate()
    {
        $.get('/books/checkForUpdate', {time: lastUpdate}, function(updateNecessary)
        {
            if(updateNecessary === true)
            {
                alert('update necessary');
                // now reload the page or use an additional AJAX request for updating the content
            }
            else
            {
                queueUpdateCheck();
            }
        },
        'json');
    }

    function queueUpdateCheck()
    {
        setTimeout(checkForUpdate, 5000);
    }

    queueUpdateCheck();
});
</script>


使用触发器

另一种选择是使用触发器.您需要一个附加表,该表使用例如表名连接表和时间值,以及两个触发器,一个用于插入,一个用于更新.然后,这些触发器可以更新自定义信息表.


Using Triggers

Another option would be using triggers. You'd need an additional table that connects tables and time values using for example the table name, and two triggers, one for inserts, one for updates. These triggers could then update the custom information table.

信息表

CREATE TABLE IF NOT EXISTS `table_stats` (
  `table_name` varchar(255) NOT NULL,
  `update_time` datetime NOT NULL,
  PRIMARY KEY (`table_name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

INSERT INTO `table_stats` (`table_name`, `update_time`)
VALUES ('books', NOW());

触发器

CREATE TRIGGER `update_time_after_insert` AFTER INSERT ON `books`
    FOR EACH ROW 
        UPDATE `table_stats` SET `update_time` = NOW() WHERE `table_name` = 'books';

CREATE TRIGGER `update_time_after_update` AFTER UPDATE ON `books`
    FOR EACH ROW 
        UPDATE `table_stats` SET `update_time` = NOW() WHERE `table_name` = 'books';

型号:

public function getUpdateTime()
{   
    $db = $this->getDataSource();

    $result = $db->fetchAll('
        SELECT
            UNIX_TIMESTAMP(update_time) AS update_time
        FROM
            `table_stats`
        WHERE
            `table_name` = ?',

        array
        (
            $this->table
        )
    );

    if(empty($result) || !isset($result[0][0]['update_time']))
    {
        return false;
    }

    return (int)$result[0][0]['update_time'];
}

控制器视图与上一个示例相同.

Controller and View would be the same as in the previous example.

现在,最后一个选项将是比较行数,这当然仅适用于插入.在此示例中,模型将保持不变.

Now the last option would be comparing the row count, which would of course only work for inserts. In this example the Model would stay untouched.

控制器:

public function list_books()
{
    $this->set('rowCount', $this->Books->find('count'));

    $this->Books->recursive = 0;
    $this->paginate = array('order' => array('Serial_No' => 'DESC'));
    $this->set('All_Books', $this->paginate());
}

public function checkForUpdate($rowCount)
{
    $updateNecessary = $this->Books->find('count') != (int)$rowCount;
    return new CakeResponse(array('body' => json_encode($updateNecessary)));
}

查看:

<script>
jQuery(function($)
{
    var rowCount = <?php echo $rowCount; ?>;

    function checkForUpdate()
    {
        $.get('/books/checkForUpdate', {rowCount: rowCount}, function(updateNecessary)
        {
            if(updateNecessary === true)
            {
                alert('update necessary');
                // now reload the page or use an additional AJAX request for updating the content
            }
            else
            {
                queueUpdateCheck();
            }
        },
        'json');
    }

    function queueUpdateCheck()
    {
        setTimeout(checkForUpdate, 5000);
    }

    queueUpdateCheck();
});
</script>


与更新检查一起检索数据

当然,您也可以将可能的数据与更新检查一起提交,以避免出现其他请求.例如:


Retrieving data together with the update check

Of course you could also submit possible data together with the update check, in order to avoid additional requests. For example:

模型

public function checkForUpdate($time)
{
    $data = '';

    $updateAvailable = $this->Books->getUpdateTime() > (int)$time;
    if($updateAvailable)
    {
        $this->set('books', $this->Books->find('all'));

        // render /Elements/books.ctp in ajax.ctp layout and grab the rendered content
        $this->viewPath = 'Elements';
        $view = $this->render('books', 'ajax');
        $data = $view->body();
    }

    $body = compact('updateAvailable', 'data');

    return new CakeResponse(array('body' => json_encode($body)));
}

查看

<script>
jQuery(function($)
{
    var lastUpdate = <?php echo $lastUpdate; ?>;

    function checkForUpdate()
    {
        $.get('/books/checkForUpdate', {time: lastUpdate}, function(response)
        {
            if(response.updateAvailable === true)
            {
                // the data is already available, so directly update the content
                $('#content').html(response.data);
            }

            queueUpdateCheck();
        },
        'json');
    }

    function queueUpdateCheck()
    {
        setTimeout(checkForUpdate, 5000);
    }

    queueUpdateCheck();
});
</script>

这篇关于每次在db表中插入一条记录时,更新CakePhp View的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆