Как избежать повторения пути в URL в php?

#php #laravel

#php #laravel

Вопрос:

У меня есть URL-адрес, например

 http://localhost:8080/laravel/api/data/create/

  

Где /laravel/api путь из файла конфигурации

и /data/create/ это путь, который я использовал traits в.

Проблема возникает каждый раз, когда я запускаю функцию с именем connection() несколько раз,

В Tinker, если я сделаю

 $data = new Sample;
$data->connection();
http://localhost:8080/laravel/api/data/create/
$data->connection();
http://localhost:8080/laravel/api/data/create/data/create/
$data->connection();
http://localhost:8080/laravel/api/data/create/data/create/data/create/
  

Путь /data/create/ повторяется каждый раз, когда я выполняю connection() .

Так не должно быть, путь должен быть добавлен только один раз, если мы выполняем connection() , как показано ниже.

 $data->connection();
http://localhost:8080/laravel/api/data/create/
  

Я использую цепочку методов для добавления пути.

 protected $resource[]; //is declared already in the code
protected $url[];
public function addPath()
{
        $old_uri = explode('/', $this->resource['path']);
        $add_uri = explode('/', $this->path);
        $new_uri = array_merge($old_uri, $add_uri);
        $this->resource['path'] = '/'.implode('/', array_filter($new_uri));
        return $this;
    
   }
  
 public function connection()
{
   $this->addPath()->unparse_url();
   return $url;
}
  
 private function unparse_url()
    {
        $scheme = isset($this->resource['scheme']) ? $this->resource['scheme'].'://' : '';
        $host = isset($this->resource['host']) ? $this->resource['host'] : '';
        $port = isset($this->resource['port']) ? ':'.$this->resource['port'] : '';
        $user = isset($this->resource['user']) ? $this->resource['user'] : '';
        $pass = isset($this->resource['pass']) ? ':'.$this->resource['pass'] : '';
        $pass = ($user || $pass) ? "$pass@" : '';
        $path = isset($this->resource['path']) ? $this->resource['path'] : '';
        $query = isset($this->resource['query']) ? '?'.$this->resource['query'] : '';
        $fragment = isset($this->resource['fragment']) ? '#'.$this->resource['fragment'] : '';

        $this->url = "$scheme$user$pass$host$port$path$query$fragment";

        return $this;
    }
  

Может кто-нибудь, пожалуйста, помочь решить проблему?
Спасибо.

Комментарии:

1. addPath() Метод должен выдавать кучу ошибок «неопределенной переменной», поскольку ни $resource $path одна из переменных или не определена в этом методе.

2. То же самое относится и к переменной $url в вашем connection() -методе. Я не понимаю, как этот код вообще может что-то возвращать. Это единственный код, который у вас есть в этих методах, или вы что-то удалили? Кроме того, addPath() метод поддерживает цепочку методов, но на самом деле вы не используете цепочку в опубликованном коде.

3. У меня есть unparse_url() в connection().

4. Пожалуйста, разместите весь соответствующий код как есть . Хорошо бы удалить из вопроса несвязанный код, но не удаляйте непосредственно релевантный код.

5. Где $url определено? Вы на самом деле имеете в виду return $this->url ?

Ответ №1:

Если мы не будем учитывать ваши неопределенные переменные, проблема в том, что ваш код добавляет путь каждый раз, когда вы вызываете connection() -метод, поскольку он вызывает addPath() -метод.

Если вы хотите, чтобы он добавлял его только один раз, есть несколько альтернатив.

Альтернатива 1

Если вы всегда хотите, чтобы путь был добавлен, вместо этого вы можете просто вызвать addPath() метод -из конструктора.

 public function __construct()
{
    $this->addPath()->unparse_url();
}
  

и просто connection() используйте -метод, подобный этому:

 public function connection()
{
    return $this->url;
}
  

Это будет хорошо работать, если вам не нужно использовать исходные значения $this->url и $this->resource['path'] для чего-либо, поскольку они будут изменены при создании экземпляра класса.

Альтернатива 2

Вы можете установить свойство класса в качестве флага, указывающего, был ли путь уже добавлен или нет. Затем вы просто устанавливаете этот флаг в своем addPath() -методе.

 // Default value is false, since we haven't added it yet
protected $pathAdded = false;

public function addPath()
{
    if ($this->pathAdded === false) {
        // It's still false so it hasn't been added yet
        
        $old_uri = explode('/', $this->resource['path']);
        $add_uri = explode('/', $this->path);
        $new_uri = array_merge($old_uri, $add_uri);
        $this->resource['path'] = '/'.implode('/', array_filter($new_uri));

        // Set the flag to true so we know it's already been done
        $this->pathAdded = true;
    }

    return $this;
}
  

Таким образом, он будет добавлять путь только при первом вызове этого метода.

Комментарии:

1. Спасибо, сэр!, альтернатива 1 работает нормально! У меня есть еще один вопрос, у меня есть 3 метода цепочки в connection () $this->addPath()-> addQuery()->unparse_url(); return $url; , но я не смог получить запрос для методов в URL.

2. Я понятия не имею, что вы подразумеваете под «Но я не смог получить запрос для методов в URL» . Однако, если вы столкнетесь с какой-то другой проблемой, вам следует опубликовать ее как новый вопрос. И если это сработало хорошо для вас, пожалуйста, примите ответ.

3. Нет, сэр, это та же проблема, которую я также опубликовал в коде, не могли бы вы взглянуть, после добавления альтернативы 1 в код, query не добавляется к URL. Спасибо за вашу поддержку, сэр!

4. Нет, чувак. Это не тот же вопрос, что и оригинал (до вашей правки через 25 минут после того, как я опубликовал ответ). Не двигайте штангу ворот! Это довольно неуважительно после того, как я потратил время, помогая вам с исходной проблемой.

5. У меня есть вопрос в альтернативе 2, где у меня уже есть path набор типа ` protected $path = ‘/data/create/’, можем ли мы добавить такой флаг protected $pathAdded = false; .?