简体   繁体   English

如何从 url 接收参数,模板字符串中有“*”?

[英]How do receive parameters from url, where i have "*" in template string?

I have 2 string: 1 is template of url, 2 is url string.我有 2 个字符串:1 是 url 的模板,2 是 url 字符串。 How do receive parameters from url, where i have "*" in template string?如何从 url 接收参数,模板字符串中有“*”?

I want to have possibility substitute different values instead of "*".我希望有可能替换不同的值而不是“*”。 for example: /user/{id}, /user/{id}/{name} etc, how i'ts have done in laravel (Route::get('/user/{id}', function ($id) { return 'User '.$id; });)例如:/user/{id}、/user/{id}/{name} 等,我在 laravel 中的表现如何(Route::get('/user/{id}', function ($id) { return '用户'.$id; });)

/category/*/product/* - template url, that i pass to the route (route->get(/category/*/product/*) - it's my route. /category/*/product/* - 模板 url,我传递给路线 (route->get(/category/*/product/*) - 这是我的路线。

/category/2/product/3 - url, that i get from $_SERVER['REQUEST_URI'] /category/2/product/3 - url,我从 $_SERVER['REQUEST_URI'] 获得

I need to get parameters 2 and 3 from url /category/2/product/3 by template /category/*/product/*.我需要通过模板 /category/*/product/* 从 url /category/2/product/3 获取参数 2 和 3。 also parameters can be string (such as a category like "t-shirts") or are they numeric like 2参数也可以是字符串(例如像“t-shirts”这样的类别)或者它们是像2这样的数字

if my problem can be solve preg_match() - it's will be nice!如果我的问题可以解决 preg_match() - 那就太好了!

Thank you for help!谢谢你的帮助!

I would do the following to your pattern:我会对您的模式执行以下操作:

  1. Replace the * by a regular expression pattern such as ([^/?]+) where the () are to capture the piece you want, where [^/?] means any char which is not a slash or question mark and where + means one or several times.*替换为正则表达式模式,例如([^/?]+)其中()用于捕获您想要的部分,其中[^/?]表示任何不是斜杠或问号的字符,其中+指一次或多次。

  2. Add a ^ at the beginning to say that is should start with the given URL pattern.在开头添加一个^表示应该以给定的 URL 模式开头。 This is to avoid matching /something/user/3 because we only want to match if it starts with /user/3 .这是为了避免匹配/something/user/3因为我们只想匹配它以/user/3开头。

Then for the given URL recieved from the request, I would just verify that it starts with a slash and add one if it's missing.然后对于从请求中收到的给定 URL ,我将验证它是否以斜杠开头,如果缺少则添加一个。 I don't know if a server configuration could create this case or not.我不知道服务器配置是否可以创建这种情况。 I put some in my test cases to show you.我在我的测试用例中放了一些给你看。

The PHP code: PHP 代码:

<?php

$tests = [
    [
        'pattern' => '/user/*',
        'urls' => [
            '/user/78',
            'user/78',
            '/user/78/james',
            '/user/james',
            '/user/james/edit-profile',
            '/user',
            'user/',
            '/users/list',
        ],
    ],
    [
        'pattern' => '/category/*/product/*',
        'urls' => [
            '/category/2/product/3',
            '/category/2/product/3?page=2',
            '/category/t-shirts/product/3/t-shirt-nike-blue-ocean',
            'category/t-shirts/product/4',
            '/cagegory/t-shirts',
        ],
    ],
];

foreach ($tests as $test) {
    // Get the pattern with the * syntax.
    $pattern = $test['pattern'];
    print "Pattern : $pattern\n";
    
    // Convert it into a regular expression.
    // The regex pattern delimiter is ~ instead of the usual / to make it easier.
    // Replace '~' at the end by '~i' if you want it case-insensitive.
    $pattern_regex = '~^' . str_replace('*', '([^/?]+)', $pattern) . '~';
    print "Regex   : $pattern_regex\n\n";
    
    // Test all the URLs
    foreach ($test['urls'] as $url) {
        // As the URL to test might start with a slash or not, we'll always add it if necessary.
        $url_with_leading_slash = preg_replace('~^(?=[^/])~', '/', $url);
        
        // Test the URL with the pattern.
        if (preg_match($pattern_regex, $url_with_leading_slash, $match_groups)) {
            // We don't need the full match so we drop item 0.
            array_shift($match_groups);

            print "$url\n";
            foreach ($match_groups as $i => $group) {
                print "  * --> $group\n";
            }
            print "\n";
        } else {
            print "No match for $url\n";
        }
    }
    
    print "\n" . str_repeat('-', 80) . "\n\n";
}

Result:结果:

Pattern : /user/*
Regex   : ~^/user/([^/?]+)~

/user/78
  * --> 78

user/78
  * --> 78

/user/78/james
  * --> 78

/user/james
  * --> james

/user/james/edit-profile
  * --> james

No match for /user
No match for user/
No match for /users/list

--------------------------------------------------------------------------------

Pattern : /category/*/product/*
Regex   : ~^/category/([^/?]+)/product/([^/?]+)~

/category/2/product/3
  * --> 2
  * --> 3

/category/2/product/3?page=2
  * --> 2
  * --> 3

/category/t-shirts/product/3/t-shirt-nike-blue-ocean
  * --> t-shirts
  * --> 3

category/t-shirts/product/4
  * --> t-shirts
  * --> 4

No match for /cagegory/t-shirts

--------------------------------------------------------------------------------

You can play with it here: https://onlinephp.io/c/56699你可以在这里玩: https://onlinephp.io/c/56699

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM