如何在Silex中使用Ajax查询?

时间:2021-05-14 15:48:44

In order to build my new site, I decided to try the Silex framework. I read a lot in the doc so I had no problems until now.

为了建立我的新网站,我决定尝试Silex框架。我读了很多医生的文章,所以直到现在我都没有问题。

I'm making a voting system and I'd like to use it dynamically with Ajax.

我正在制作一个投票系统,我想用Ajax动态地使用它。

So, first I declared the route :

首先我声明了路线

routes.php

routes.php

$app->match('/ajax/vote', mysite\Controller\HomeController::voteAction');

I registered the service :

我注册了服务:

app.php

app.php

$app['dao.ajax'] = $app->share(function ($app) {
    return new mysite\DAO\AjaxDAO($app['db']);
});

Then, there is the associated controller :

然后,有一个相关的控制器:

HomeController.php

HomeController.php

public function voteAction(Application $app, Request $request) {        

    $vote = new Vote();
    $vote->setVoteId($request->get('vote_id'));
    $vote->setBookId($request->get('book_id'));
    $vote->setVoterIp($request->get('IP'));

    $voteAction = $app['dao.ajax']->saveVote($vote);
    return $app['twig']->render('index.html.twig');
}

So when I click on the Vote button, it is supposed to (re)render the index page.

所以当我点击投票按钮时,它应该(重新)呈现索引页面。

My DAO class :

我的DAO类:

DAO.php

DAO.php

namespace mysite\DAO;

use Doctrine\DBAL\Connection;

abstract class DAO 
{
    private $db;

    public function __construct(Connection $db) {
        $this->db = $db;
    }

    protected function getDb() {
        return $this->db;
    }

    protected abstract function buildDomainObject($row);
}

Then, the voting function :

然后,投票功能:

AjaxDAO.php

AjaxDAO.php

namespace mysite\DAO;

use mysite\Domain\Vote;

class AjaxDAO extends DAO 
{
    protected function buildDomainObject($row) {
        $vote = new Vote();
        $vote->setVoteId($row['vote_id']);
        $vote->setBookId($row['book_id']);
        $vote->setVoterIp($row['vt_ip']);
        return $vote;
    }

    public function saveVote(Vote $vote) {

        $voteData = array(
            'vote_id' => $vote->getVoteId(),
            'book_id' => $vote->getBookId(),
            'vt_ip' => $vote->getVoterIp()
        );
        $this->getDb()->insert('t_vote', $voteData);
    }
}

The Vote class :

投票类:

Vote.php

Vote.php

namespace mysite\Domain;

class Vote
{
    private $id;

    private $vote_id;

    private $book_id;

    private $vt_ip;


    public function getId() {
        return $this->id;
    }

    public function setId($id) {
        $this->id = $id;
    }

    public function getVoteId() {
        return $this->vote_id;
    }

    public function setVoteId($vote_id) {
        $this->vote_id = $vote_id;
    }

    public function getBookId() {
        return $this->book_id;
    }

    public function setBookId($book_id) {
        $this->book_id = $book_id;
    }

    public function getVoterIp() {
        return $this->vt_ip;
    }

    public function setVoterIp($vt_ip) {
        $this->vt_ip = $vt_ip;
    }
}

Now, the jQuery with the Ajax in it :

现在,包含Ajax的jQuery:

vote.js

vote.js

$('button').on('click', function like(e) {
    $(this).off('click');
    e.preventDefault();

    var vote_id = '{{ vote_id }}';
    var book_id = $(this).attr('data-book');
    var IP = '{{ getUserIp() }}';

    if ($(this).hasClass('active')) {
        $.ajax({
            type: 'POST',
            url: '/ajax/vote',
            data: {'POST_type': 'vote', 'book_id': book_id, 'IP': IP},
            success: function(html) {
                $('button').removeClass('active').addClass('disabled');
            },
            error: function() {
                alert('error');
            }
        });
    };
});

As you may have understand, when I click the button VOTE, I have an error alert. When I visit the link mysite/ajax/vote, I have this error :

正如您所理解的,当我单击按钮投票时,我有一个错误警报。当我访问mysite/ajax/vote的链接时,我有以下错误:

Notice: Undefined property: mysite\DAO\AjaxDAO::$request

I checked in the Official Documentation and in previous * questions but I found only the question 22011254 and it didn't help me...

我查阅了官方文档和之前的*问题,但我只找到了问题22011254,它对我没有帮助……

EDIT : I just read that Silex supports only Json data exchange with Ajax. Maybe is this the problem?

编辑:我刚看到Silex只支持与Ajax的Json数据交换。也许这就是问题所在?

3 个解决方案

#1


1  

There is error in AjaxDAO.php method saveVote. You try to use property $this->request that is not defined in this class. Better set vote fields in controller and that transmit it to saveVote.

AjaxDAO中有错误。saveVote php方法。您尝试使用属性$this->请求,该请求在类中没有定义。更好地在控制器中设置投票字段,并将其传输到saveVote。

HomeController.php

HomeController.php

public function voteAction(Application $app, Request $request) {
    ...

    $vote = new Vote();
    $vote->setVoteId($request->get('vote_id'));
    $vote->setBookId($request->get('book_id'));
    $vote->setVoterIp($request->get('vt_ip'));

    $voteAction = $app['dao.ajax']->saveVote($vote);

    ...
}

AjaxDAO.php

AjaxDAO.php

public function saveVote(Vote $vote) {
    $voteData = array(
        'vote_id' => $vote->getVoteId(),
        ...
    );
    $this->getDb()->insert('t_vote', $voteData);
}

#2


2  

It's worth checking what is in the headers sent with your ajax request. In silex application/json requests are not handled as standard x-form. You can remedy this using a solution mentioned in silex cookbook (this valid for both 2.* and 1.3.*).

值得检查与ajax请求一起发送的头中的内容。在silex应用程序/json请求不作为标准x-form处理。您可以使用silex cookbook中提到的解决方案解决这个问题(这对两个都有效)。*和1.3 . *)。

As for the notice I'd start looking here:

关于通知,我从这里开始看:

$vote->setVoteId($request->get('vote_id'));
$vote->setBookId($request->get('book_id'));
$vote->setVoterIp($request->get('IP'));

If you're making some non-standard post request maybe those $request->get method calls return something other than you expect (e.g. request object?). Since you have no validation or sanitisation going on you might have not noticed.

如果你正在进行一些非标准的post请求,也许那些$request->get方法调用会返回一些出乎你意料的东西(例如request object?)由于您没有进行验证或消毒,您可能没有注意到。

You can also change this:

你也可以改变这一点:

$app->match('/ajax/vote', mysite\Controller\HomeController::voteAction');

to:

:

$app->post('/ajax/vote', mysite\Controller\HomeController::voteAction');

since match without specified methods will match every type of request. Might not matter now, but will save you trouble later.

因为没有指定方法的match将匹配所有类型的请求。现在可能不重要,但以后会为你省去麻烦。

#3


0  

I have not used Silex and i am not that familiar with it but viewing documentation.

我没有使用过Silex,我对它并不熟悉,只是查看文档。

You can create controllers for most HTTP methods. Just call one of these methods on your application: get, post, put, delete, patch.

您可以为大多数HTTP方法创建控制器。只需在应用程序中调用其中一个方法:get、post、put、delete、patch。

In your HomeController.php you use get(), shouldn't this HTTP method be used in ajax as well?

在你HomeController。您使用的php get(),这个HTTP方法不也应该在ajax中使用吗?

Example

例子

$('button').on('click', function like(e) {
    $(this).off('click');
    e.preventDefault();

    var vote_id = 'Vote ID';
    var book_id = $(this).attr('data-book');
    var IP = getUserIp();

    if ($(this).hasClass('active')) {
        $.ajax({
            type: 'GET',
            url: '/ajax/vote?vote_id='+vote_id+'&book_id='+book_id+'vt_ip='+IP,
            success: function(html) {
                $('button').removeClass('active').addClass('disabled');
            },
            error: function() {
                alert('error');
            }
        });
    };
});

#1


1  

There is error in AjaxDAO.php method saveVote. You try to use property $this->request that is not defined in this class. Better set vote fields in controller and that transmit it to saveVote.

AjaxDAO中有错误。saveVote php方法。您尝试使用属性$this->请求,该请求在类中没有定义。更好地在控制器中设置投票字段,并将其传输到saveVote。

HomeController.php

HomeController.php

public function voteAction(Application $app, Request $request) {
    ...

    $vote = new Vote();
    $vote->setVoteId($request->get('vote_id'));
    $vote->setBookId($request->get('book_id'));
    $vote->setVoterIp($request->get('vt_ip'));

    $voteAction = $app['dao.ajax']->saveVote($vote);

    ...
}

AjaxDAO.php

AjaxDAO.php

public function saveVote(Vote $vote) {
    $voteData = array(
        'vote_id' => $vote->getVoteId(),
        ...
    );
    $this->getDb()->insert('t_vote', $voteData);
}

#2


2  

It's worth checking what is in the headers sent with your ajax request. In silex application/json requests are not handled as standard x-form. You can remedy this using a solution mentioned in silex cookbook (this valid for both 2.* and 1.3.*).

值得检查与ajax请求一起发送的头中的内容。在silex应用程序/json请求不作为标准x-form处理。您可以使用silex cookbook中提到的解决方案解决这个问题(这对两个都有效)。*和1.3 . *)。

As for the notice I'd start looking here:

关于通知,我从这里开始看:

$vote->setVoteId($request->get('vote_id'));
$vote->setBookId($request->get('book_id'));
$vote->setVoterIp($request->get('IP'));

If you're making some non-standard post request maybe those $request->get method calls return something other than you expect (e.g. request object?). Since you have no validation or sanitisation going on you might have not noticed.

如果你正在进行一些非标准的post请求,也许那些$request->get方法调用会返回一些出乎你意料的东西(例如request object?)由于您没有进行验证或消毒,您可能没有注意到。

You can also change this:

你也可以改变这一点:

$app->match('/ajax/vote', mysite\Controller\HomeController::voteAction');

to:

:

$app->post('/ajax/vote', mysite\Controller\HomeController::voteAction');

since match without specified methods will match every type of request. Might not matter now, but will save you trouble later.

因为没有指定方法的match将匹配所有类型的请求。现在可能不重要,但以后会为你省去麻烦。

#3


0  

I have not used Silex and i am not that familiar with it but viewing documentation.

我没有使用过Silex,我对它并不熟悉,只是查看文档。

You can create controllers for most HTTP methods. Just call one of these methods on your application: get, post, put, delete, patch.

您可以为大多数HTTP方法创建控制器。只需在应用程序中调用其中一个方法:get、post、put、delete、patch。

In your HomeController.php you use get(), shouldn't this HTTP method be used in ajax as well?

在你HomeController。您使用的php get(),这个HTTP方法不也应该在ajax中使用吗?

Example

例子

$('button').on('click', function like(e) {
    $(this).off('click');
    e.preventDefault();

    var vote_id = 'Vote ID';
    var book_id = $(this).attr('data-book');
    var IP = getUserIp();

    if ($(this).hasClass('active')) {
        $.ajax({
            type: 'GET',
            url: '/ajax/vote?vote_id='+vote_id+'&book_id='+book_id+'vt_ip='+IP,
            success: function(html) {
                $('button').removeClass('active').addClass('disabled');
            },
            error: function() {
                alert('error');
            }
        });
    };
});