首页 > 解决方案 > Can't Http Delete Method on Simple PHP API using Silex - 超出子请求限制

问题描述

我试图通过编写一个简单的购物清单应用程序来掌握 PHP 和 REST。目前,我可以 GET 和 POST 到 API,但是,每次我尝试运行 DELETE 方法时,我的 apache 日志中都会出现 500 Internal Server 错误和以下内容:

[Mon Jul 22 12:39:51.554267 2019] [socache_shmcb:debug] [pid 12459] mod_socache_shmcb.c(495): AH00831: 
socache_shmcb_store (0x0c -> subcache 12)                                                              
[Mon Jul 22 12:39:51.554393 2019] [socache_shmcb:debug] [pid 12459] mod_socache_shmcb.c(849): AH00847: 
insert happened at idx=0, data=(0:32)                                                                  
[Mon Jul 22 12:39:51.554432 2019] [socache_shmcb:debug] [pid 12459] mod_socache_shmcb.c(854): AH00848: 
finished insert, subcache: idx_pos/idx_used=0/1, data_pos/data_used=0/222                              
[Mon Jul 22 12:39:51.554459 2019] [socache_shmcb:debug] [pid 12459] mod_socache_shmcb.c(516): AH00834: 
leaving socache_shmcb_store successfully                                                               
[Mon Jul 22 12:39:51.560611 2019] [ssl:debug] [pid 12459] ssl_engine_kernel.c(377): [client 192.168.69.
2:51738] AH02034: Initial (No.1) HTTPS request received for child 3 (server smart-shopper.notsoslow.tk:
443)                                                                                                   
[Mon Jul 22 12:39:51.561836 2019] [authz_core:debug] [pid 12459] mod_authz_core.c(809): [client 192.168
.69.2:51738] AH01626: authorization result of Require all granted: granted                             
[Mon Jul 22 12:39:51.561898 2019] [authz_core:debug] [pid 12459] mod_authz_core.c(809): [client 192.168
.69.2:51738] AH01626: authorization result of <RequireAny>: granted                                    
[Mon Jul 22 12:39:51.563184 2019] [core:error] [pid 12459] [client 192.168.69.2:51738] AH00125: Request
 exceeded the limit of 10 subrequest nesting levels due to probable configuration error. Use 'LimitInte
rnalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.            
[Mon Jul 22 12:39:51.563308 2019] [core:debug] [pid 12459] core.c(3833): [client 192.168.69.2:51738] AH
00121: r->uri = /smart-shopper-api/shopping-list/index.php                                             
[Mon Jul 22 12:39:51.563334 2019] [core:debug] [pid 12459] core.c(3847): [client 192.168.69.2:51738] AH
00123: subrequested from r->uri = /smart-shopper-api/shopping-list/index.php                           
[Mon Jul 22 12:39:51.563358 2019] [core:debug] [pid 12459] core.c(3847): [client 192.168.69.2:51738] AH
00123: subrequested from r->uri = /smart-shopper-api/shopping-list/index.php                           
[Mon Jul 22 12:39:51.563381 2019] [core:debug] [pid 12459] core.c(3847): [client 192.168.69.2:51738] AH
00123: subrequested from r->uri = /smart-shopper-api/shopping-list/index.php                           
[Mon Jul 22 12:39:51.563402 2019] [core:debug] [pid 12459] core.c(3847): [client 192.168.69.2:51738] AH
00123: subrequested from r->uri = /smart-shopper-api/shopping-list/index.php                           
[Mon Jul 22 12:39:51.563423 2019] [core:debug] [pid 12459] core.c(3847): [client 192.168.69.2:51738] AH
00123: subrequested from r->uri = /smart-shopper-api/shopping-list/index.php                           
[Mon Jul 22 12:39:51.563444 2019] [core:debug] [pid 12459] core.c(3847): [client 192.168.69.2:51738] AH
00123: subrequested from r->uri = /smart-shopper-api/shopping-list/index.php                           
[Mon Jul 22 12:39:51.563519 2019] [core:debug] [pid 12459] core.c(3847): [client 192.168.69.2:51738] AH
00123: subrequested from r->uri = /smart-shopper-api/shopping-list/index.php                           
[Mon Jul 22 12:39:51.563545 2019] [core:debug] [pid 12459] core.c(3847): [client 192.168.69.2:51738] AH
00123: subrequested from r->uri = /smart-shopper-api/shopping-list/index.php                           
[Mon Jul 22 12:39:51.563566 2019] [core:debug] [pid 12459] core.c(3847): [client 192.168.69.2:51738] AH
00123: subrequested from r->uri = /smart-shopper-api/shopping-list/index.php                           
[Mon Jul 22 12:39:51.563590 2019] [core:debug] [pid 12459] core.c(3847): [client 192.168.69.2:51738] AH
00123: subrequested from r->uri = /smart-shopper-api/shopping-list/1                                   
[Mon Jul 22 12:39:51.564841 2019] [ssl:debug] [pid 12459] ssl_engine_io.c(1106): [client 192.168.69.2:5
1738] AH02001: Connection closed to child 3 with standard shutdown (server smart-shopper.notsoslow.tk:4
43)

这是我的 index.php 的样子:

<?php
require 'vendor/autoload.php';
include 'bootstrap.php';

use smart_shopper_api\Models\ShoppingListItem;
use smart_shopper_api\Middleware\Logging as ApiLogging;
use Symfony\Component\HttpFoundation\Request as Request;
use Symfony\Component\HttpFoundation\Response as Response;

$app = new Silex\Application();
// never use in production
$app['debug'] = true;
ini_set('display_errors', 'On');
error_reporting(E_ALL);

$app->before(function($request, $app) {
    ApiLogging::log($request, $app);
});

$app->get('/shopping-list', function () use ($app) {
    $_shoppingList = new ShoppingListItem();
    $shoppingListItems = $_shoppingList->all();

    $payload = [];

    foreach ($shoppingListItems as $_item) {
        $payload[$_item->id] = [
            'name' => $_item->name,
            'description' => $_item->description,
            'price' => $_item->price,
            'created_at' => $_item->created_at,
            'updated_at' => $_item->updated_at
        ];
    }

    return $app->json($payload, 200);
});

$app->post('/shopping-list', function(Request $request) use($app) {

    $_name = $request->get('name');
    $_description = $request->get('description');
    $_price = $request->get('price');

    $shoppingListItem = new ShoppingListItem();
    $shoppingListItem->name = $_name;
    $shoppingListItem->description = $_description;
    $shoppingListItem->price = $_price;

    $shoppingListItem->save();

    if($shoppingListItem->id) {
        $code = 201;
        $payload = [
            'id' => $shoppingListItem->id
        ];
    } else {
        $code = 400;
        $payload = [];
    }

    return $app->json($payload, $code);
});

$app->delete('/shopping-list/{item_id}', function($item_id) use($app) {
    $shoppingListItem = ShoppingListItem::where('id', $item_id);
    if($shoppingListItem != null) {
        $shoppingListItem->delete();
    } else {
        return new Response('Shopping List Item not found. It may be deleted before or it may have never existed.', 200);
    }

    if($shoppingListItem->exists) {
        return new Response('', 400);
    } else {
        return new Response('', 204);
    }
});

$app->get('/test', function () use ($app) {

    return "This route confirms that Silex is running. This doesn't contain a call to the Database However.";
});

$app->run();

我做了一些研究“AH00125:由于可能的配置错误,请求超出了 10 个子请求嵌套级别的限制。如有必要,请使用 'LimitInternalRecursion' 来增加限制。使用 'LogLevel debug' 来获取回溯。” 意思是,我能够将内部递归更改为 1000,但是它创建了 1000 个条目,所以有些东西在循环,我无法指望。

这是我的虚拟主机配置:

<VirtualHost *:443>
        # The ServerName directive sets the request scheme, hostname and port that
        # the server uses to identify itself. This is used when creating
        # redirection URLs. In the context of virtual hosts, the ServerName
        # specifies what hostname must appear in the request's Host: header to
        # match this virtual host. For the default virtual host (this file) this
        # value is not decisive as it is used as a last resort host regardless.
        # However, you must set it for any further virtual host explicitly.
        #ServerName www.example.com

        SSLEngine On
        SSLCertificateFile /etc/ssl/apache2/smart-shopper/cert.pem
        SSLCertificateKeyFile /etc/ssl/apache2/smart-shopper/key.pem

        ServerName smart-shopper.example.com
        ServerAdmin webmaster@localhost
        Alias /smart-shopper-api/ /var/www/html/smart-shopper/smart-shopper-api/
        <Directory "/var/www/html/smart-shopper/smart-shopper-api/">
                FallbackResource index.php
        </Directory>

        DocumentRoot /var/www/html/smart-shopper/smart-shopper-api/

        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/smart-shopper-error.log
        CustomLog ${APACHE_LOG_DIR}/smart-shopper-access.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf
</VirtualHost>

任何帮助将不胜感激。

标签: phpapacheresteloquentsilex

解决方案


好的,我无法在 Apache 中对此进行排序,因此我更改了 Web 服务器软件。

在 Web 服务器在 Ubuntu Server 18.04 上运行 Apache2 之前,我已将其更改为 nginx。这是我的 Nginx 虚拟主机配置对于可能遇到相同问题的任何人的外观:

server {
        listen 443 ssl default_server;
        ssl_certificate /etc/ssl/nginx/certs/cert.crt;
        ssl_certificate_key /etc/ssl/nginx/certs/key.key;
        #listen [::]:80 default_server;

        # SSL configuration
        #
        # listen 443 ssl default_server;
        # listen [::]:443 ssl default_server;
        #
        # Note: You should disable gzip for SSL traffic.
        # See: https://bugs.debian.org/773332
        #
        # Read up on ssl_ciphers to ensure a secure configuration.
        # See: https://bugs.debian.org/765782
        #
        # Self signed certs generated by the ssl-cert package
        # Don't use them in a production server!
        #
        # include snippets/snakeoil.conf;

        root /var/www/html/smart-shopper/smart-shopper-api;

        # Add index.php to the list if you are using PHP
        index index.php index.html index.htm index.nginx-debian.html;

        server_name mywebsite.com;

        if (!-e $request_filename)
        {
                rewrite ^/(.*)$ /index.php?/$1 last;
                break;
        }

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                #try_files $uri $uri/ =404;
                try_files $uri /index.php$is_args$args;

        }

        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/run/php/php7.2-fpm.sock;
        }

        location ~ /\.ht {
                deny all;
        }

        # pass PHP scripts to FastCGI server
        #
        #location ~ \.php$ {
        #       include snippets/fastcgi-php.conf;
        #
        #       # With php-fpm (or other unix sockets):
        #       fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
        #       # With php-cgi (or other tcp sockets):
        #       fastcgi_pass 127.0.0.1:9000;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #       deny all;
        #}
}

所以它现在正在工作,这是主要的事情。现在我将 Nginx 用于一切,因为我无法在 Apache 中解决这个问题。所以 bazaar 你不能运行 DELETE 方法来重写 index.php。也许有人可能知道答案,但目前这是最好的方法。


推荐阅读