Yii 返回大数据集时出现内部服务器错误 (500)

发布于 2024-12-21 15:20:35 字数 3202 浏览 1 评论 0原文

我有一个 Yii Web 服务 actionQuery,它根据四个参数查询模型。总共大约有 1700 个项目需要查询,而且我使用的是一个非常糟糕的网络主机 (iPage)。当我运行不带参数或极其常见的参数(例如字符串 name 中的“a”)的查询时,我希望看到所有或几乎所有行。相反,我返回了 500 内部服务器错误,该错误显然不是由 Yii 产生的,因此这是一个非常严重的错误。当我尝试将其缩小到大约 700 或 800 行时,需要一段时间,但它完成了。如何纠正大数据集产生 500 个内部服务器错误的错误?这是最大执行时间问题吗?我需要对 CDBCriteria 做一些不同的事情吗?

这是 actionQuery,诚然,它的编码相当糟糕。

 public function actionQuery()
    {
                $this->_checkAuth();

        switch ($_GET['model'])
                {
                        case 'dogFood':
                                $criteria = new CDbCriteria();
                                if ($_GET['name'] && $_GET['name'] !== '0') {
                                        $criteria->addSearchCondition('name_df', $_GET['name']);
                                }
                                if ($_GET['ingredients'] && $_GET['ingredients'] !== '0') {
                                        $ingredientsArray = explode(',',$_GET['ingredients']);
                                        foreach ($ingredientsArray as $ingredient) {
                                                $criteria->addSearchCondition('ingredients_df', $ingredient);
                                        }
                                }
                                if ($_GET['brand'] && $_GET['brand'] != 0) {
                                        $criteria->addColumnCondition(array('brand_df' => $_GET['brand']));
                                }
                                if ($_GET['brandstring'] && $_GET['brandstring'] !== 0) {
                                        $criteriaForBrand = new CDbCriteria();
                                        $criteriaForBrand->addSearchCondition('name_dfb', $_GET['brandstring']);
                                        $brandInQuestion = DogfoodbrandDfb::model()->find($criteriaForBrand);
                                        $brandId = $brandInQuestion->id_dfb;
                                        $criteria->addColumnCondition(array('brand_df' => $brandId));
                                }
                                $models = DogfoodDf::model()->findAll($criteria);
                                break;
                        default:
                                $this->_sendResponse(501, sprintf(
                                        'Error: Mode <b>query</b> is not implemented for model <b>%s</b>',
                                        $_GET['model']));
                                exit;
                }

                if (empty($models)) {
                        $this->_sendResponse(200,
                                sprintf('No items were found for model <b>%s</b>', $_GET['model']));
                }
                else {
                        $rows = array();

                        foreach ($models as $model) {
                                $rows[] = $model->attributes;
                        }

                        $this->_sendResponse(200, CJSON::encode($rows));
                }
    }

I have a Yii web service actionQuery that queries a model based on four parameters. There are about 1700 items to be queried total and I'm using a pretty bad web host (iPage). When I run a query with no parameters or extremely common parameters like "a" in string name, I expect to see all or almost all of the rows. Instead I get back a 500 Internal server error that is obviously not being produced by Yii, so it's a pretty bad error. When I try to narrow it down to around 700 or 800 rows, it takes a while but it gets done. How can I correct this error of large data sets producing 500 internal server errors? Is it a max execution time issue? Is there something I need to be doing differently with CDBCriteria?

Here is actionQuery, which is admittedly coded quite poorly.

 public function actionQuery()
    {
                $this->_checkAuth();

        switch ($_GET['model'])
                {
                        case 'dogFood':
                                $criteria = new CDbCriteria();
                                if ($_GET['name'] && $_GET['name'] !== '0') {
                                        $criteria->addSearchCondition('name_df', $_GET['name']);
                                }
                                if ($_GET['ingredients'] && $_GET['ingredients'] !== '0') {
                                        $ingredientsArray = explode(',',$_GET['ingredients']);
                                        foreach ($ingredientsArray as $ingredient) {
                                                $criteria->addSearchCondition('ingredients_df', $ingredient);
                                        }
                                }
                                if ($_GET['brand'] && $_GET['brand'] != 0) {
                                        $criteria->addColumnCondition(array('brand_df' => $_GET['brand']));
                                }
                                if ($_GET['brandstring'] && $_GET['brandstring'] !== 0) {
                                        $criteriaForBrand = new CDbCriteria();
                                        $criteriaForBrand->addSearchCondition('name_dfb', $_GET['brandstring']);
                                        $brandInQuestion = DogfoodbrandDfb::model()->find($criteriaForBrand);
                                        $brandId = $brandInQuestion->id_dfb;
                                        $criteria->addColumnCondition(array('brand_df' => $brandId));
                                }
                                $models = DogfoodDf::model()->findAll($criteria);
                                break;
                        default:
                                $this->_sendResponse(501, sprintf(
                                        'Error: Mode <b>query</b> is not implemented for model <b>%s</b>',
                                        $_GET['model']));
                                exit;
                }

                if (empty($models)) {
                        $this->_sendResponse(200,
                                sprintf('No items were found for model <b>%s</b>', $_GET['model']));
                }
                else {
                        $rows = array();

                        foreach ($models as $model) {
                                $rows[] = $model->attributes;
                        }

                        $this->_sendResponse(200, CJSON::encode($rows));
                }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

云雾 2024-12-28 15:20:35

您很可能内存不足。 PHP 程序可以使用多少内存是有限制的:您应该在 error.log 中看到内存超出消息。

您可以尝试增加线程或此特定脚本允许的内存,但首先在错误日志中验证这是否是问题所在。

Most likely you are running out of memory. There is a limit set how much memory a PHP program can use: you should see memory exceeded messages in your error.log.

You can try and up the allowed memory for a thread, or for this specific script, but verify in your error log first that this is the issue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文