我正试图将我的Laravel版本从5.5
升级到5.6
。我已经按照Laravel官网的说明进行了操作,但是出现了以下错误:
Your requirements could not be resolved to an installable set of packages.
Problem 1
- The requested package laravel/framework 5.6.* is satisfiable by laravel/framework[5.6.x-dev] but these conflict with your requirements or minimum-stability.
所以,我更改了我的composer.json
文件并添加了两行:**"minimum-stability": "dev", "prefer-stable": true,**
根据这个 laracast讨论中第一个答案的建议。
一切似乎都正常工作,直到我收到另一个错误:
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 0 installs, 6 updates, 0 removals
- Updating sebastian/diff (2.0.1 => 3.0.0): Downloading (100%)
- Updating phpunit/phpunit-mock-objects (5.0.6 => 6.0.0): Downloading (100%) - Updating phpunit/php-timer (1.0.9 => 2.0.0): Downloading (100%)
- Updating phpunit/php-token-stream (2.0.2 => 3.0.0): Downloading (100%) - Updating phpunit/php-code-coverage (5.3.0 => 6.0.1): Downloading (100%) - Updating phpunit/phpunit (6.5.6 => 7.0.0): Downloading (100%)
Writing lock file
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover
In trustedproxy.php line 66:
Undefined class constant 'HEADER_CLIENT_IP'
Script @php artisan package:discover handling the post-autoload-dump event returned with error code 1
第66行的问题是Illuminate\Http\Request::HEADER_CLIENT_IP => 'X_FORWARDED_FOR',。 我在stackoverflow上搜索过其他帖子,但仍然没有找到解决方法。我最后尝试的是运行命令composer self-update和composer global update,这在composer dump-autoload not recognized command的帖子中有提到。
此外,我无法删除"minimum-stability": "dev","prefer-stable": true,因为如果这样做,我将会得到以下错误:
- Installation request for laravel/framework 5.6.* -> satisfiable by laravel/framework[5.6.x-dev].
- Removal request for laravel/framework == 5.6.9999999.9999999-dev
我已经分别附上了我的composer.json文件和trustedproxy.php文件。非常感谢您的帮助。
{
"name": "laravel/laravel",
"description": "The Laravel Framework.",
"minimum-stability": "dev",
"prefer-stable": true,
"keywords": ["framework", "laravel"],
"license": "MIT",
"type": "project",
"require": {
"php": ">=7.1.3",
"fideloper/proxy": "~3.3",
"laravel/framework": "5.6.*",
"laravel/tinker": "~1.0"
},
"require-dev": {
"filp/whoops": "~2.0",
"fzaninotto/faker": "~1.4",
"mockery/mockery": "~1.0",
"phpunit/phpunit": "~7.0",
"symfony/thanks": "^1.0"
},
"autoload": {
"classmap": [
"database/seeds",
"database/factories"
],
"psr-4": {
"App\\": "app/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"extra": {
"laravel": {
"dont-discover": [
]
}
},
"scripts": {
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"@php artisan key:generate"
],
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover"
]
},
"config": {
"preferred-install": "dist",
"sort-packages": true,
"optimize-autoloader": true
}
}
trustedproxy.php (第66行出错--> Illuminate\Http\Request::HEADER_CLIENT_IP => 'X_FORWARDED_FOR',)
<?php
return [
/*
* Set trusted proxy IP addresses.
*
* Both IPv4 and IPv6 addresses are
* supported, along with CIDR notation.
*
* The "*" character is syntactic sugar
* within TrustedProxy to trust any proxy
* that connects directly to your server,
* a requirement when you cannot know the address
* of your proxy (e.g. if using Rackspace balancers).
*
* The "**" character is syntactic sugar within
* TrustedProxy to trust not just any proxy that
* connects directly to your server, but also
* proxies that connect to those proxies, and all
* the way back until you reach the original source
* IP. It will mean that $request->getClientIp()
* always gets the originating client IP, no matter
* how many proxies that client's request has
* subsequently passed through.
*/
'proxies' => [
'192.168.1.10',
],
/*
* Or, to trust all proxies that connect
* directly to your server, uncomment this:
*/
# 'proxies' => '*',
/*
* Or, to trust ALL proxies, including those that
* are in a chain of forwarding, uncomment this:
*/
# 'proxies' => '**',
/*
* Default Header Names
*
* Change these if the proxy does
* not send the default header names.
*
* Note that headers such as X-Forwarded-For
* are transformed to HTTP_X_FORWARDED_FOR format.
*
* The following are Symfony defaults, found in
* \Symfony\Component\HttpFoundation\Request::$trustedHeaders
*
* You may optionally set headers to 'null' here if you'd like
* for them to be considered untrusted instead. Ex:
*
* Illuminate\Http\Request::HEADER_CLIENT_HOST => null,
*
* WARNING: If you're using AWS Elastic Load Balancing or Heroku,
* the FORWARDED and X_FORWARDED_HOST headers should be set to null
* as they are currently unsupported there.
*/
'headers' => [
(defined('Illuminate\Http\Request::HEADER_FORWARDED') ? Illuminate\Http\Request::HEADER_FORWARDED : 'forwarded') => 'FORWARDED',
Illuminate\Http\Request::HEADER_CLIENT_IP => 'X_FORWARDED_FOR',
Illuminate\Http\Request::HEADER_CLIENT_HOST => 'X_FORWARDED_HOST',
Illuminate\Http\Request::HEADER_CLIENT_PROTO => 'X_FORWARDED_PROTO',
Illuminate\Http\Request::HEADER_CLIENT_PORT => 'X_FORWARDED_PORT',
]
];
Illuminate\Http\Request 文件:
<?php
namespace Illuminate\Http;
use Closure;
use ArrayAccess;
use RuntimeException;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Support\Traits\Macroable;
use Illuminate\Contracts\Support\Arrayable;
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
class Request extends SymfonyRequest implements Arrayable, ArrayAccess
{
use Concerns\InteractsWithContentTypes,
Concerns\InteractsWithFlashData,
Concerns\InteractsWithInput,
Macroable;
/**
* The decoded JSON content for the request.
*
* @var \Symfony\Component\HttpFoundation\ParameterBag|null
*/
protected $json;
/**
* All of the converted files for the request.
*
* @var array
*/
protected $convertedFiles;
/**
* The user resolver callback.
*
* @var \Closure
*/
protected $userResolver;
/**
* The route resolver callback.
*
* @var \Closure
*/
protected $routeResolver;
/**
* Create a new Illuminate HTTP request from server variables.
*
* @return static
*/
public static function capture()
{
static::enableHttpMethodParameterOverride();
return static::createFromBase(SymfonyRequest::createFromGlobals());
}
/**
* Return the Request instance.
*
* @return $this
*/
public function instance()
{
return $this;
}
/**
* Get the request method.
*
* @return string
*/
public function method()
{
return $this->getMethod();
}
/**
* Get the root URL for the application.
*
* @return string
*/
public function root()
{
return rtrim($this->getSchemeAndHttpHost().$this->getBaseUrl(), '/');
}
/**
* Get the URL (no query string) for the request.
*
* @return string
*/
public function url()
{
return rtrim(preg_replace('/\?.*/', '', $this->getUri()), '/');
}
/**
* Get the full URL for the request.
*
* @return string
*/
public function fullUrl()
{
$query = $this->getQueryString();
$question = $this->getBaseUrl().$this->getPathInfo() == '/' ? '/?' : '?';
return $query ? $this->url().$question.$query : $this->url();
}
/**
* Get the full URL for the request with the added query string parameters.
*
* @param array $query
* @return string
*/
public function fullUrlWithQuery(array $query)
{
$question = $this->getBaseUrl().$this->getPathInfo() == '/' ? '/?' : '?';
return count($this->query()) > 0
? $this->url().$question.http_build_query(array_merge($this->query(), $query))
: $this->fullUrl().$question.http_build_query($query);
}
/**
* Get the current path info for the request.
*
* @return string
*/
public function path()
{
$pattern = trim($this->getPathInfo(), '/');
return $pattern == '' ? '/' : $pattern;
}
/**
* Get the current decoded path info for the request.
*
* @return string
*/
public function decodedPath()
{
return rawurldecode($this->path());
}
/**
* Get a segment from the URI (1 based index).
*
* @param int $index
* @param string|null $default
* @return string|null
*/
public function segment($index, $default = null)
{
return Arr::get($this->segments(), $index - 1, $default);
}
/**
* Get all of the segments for the request path.
*
* @return array
*/
public function segments()
{
$segments = explode('/', $this->decodedPath());
return array_values(array_filter($segments, function ($value) {
return $value !== '';
}));
}
/**
* Determine if the current request URI matches a pattern.
*
* @param dynamic $patterns
* @return bool
*/
public function is(...$patterns)
{
foreach ($patterns as $pattern) {
if (Str::is($pattern, $this->decodedPath())) {
return true;
}
}
return false;
}
/**
* Determine if the route name matches a given pattern.
*
* @param dynamic $patterns
* @return bool
*/
public function routeIs(...$patterns)
{
return $this->route() && $this->route()->named(...$patterns);
}
/**
* Determine if the current request URL and query string matches a pattern.
*
* @param dynamic $patterns
* @return bool
*/
public function fullUrlIs(...$patterns)
{
$url = $this->fullUrl();
foreach ($patterns as $pattern) {
if (Str::is($pattern, $url)) {
return true;
}
}
return false;
}
/**
* Determine if the request is the result of an AJAX call.
*
* @return bool
*/
public function ajax()
{
return $this->isXmlHttpRequest();
}
/**
* Determine if the request is the result of an PJAX call.
*
* @return bool
*/
public function pjax()
{
return $this->headers->get('X-PJAX') == true;
}
/**
* Determine if the request is over HTTPS.
*
* @return bool
*/
public function secure()
{
return $this->isSecure();
}
/**
* Get the client IP address.
*
* @return string
*/
public function ip()
{
return $this->getClientIp();
}
/**
* Get the client IP addresses.
*
* @return array
*/
public function ips()
{
return $this->getClientIps();
}
/**
* Get the client user agent.
*
* @return string
*/
public function userAgent()
{
return $this->headers->get('User-Agent');
}
/**
* Merge new input into the current request's input array.
*
* @param array $input
* @return \Illuminate\Http\Request
*/
public function merge(array $input)
{
$this->getInputSource()->add($input);
return $this;
}
/**
* Replace the input for the current request.
*
* @param array $input
* @return \Illuminate\Http\Request
*/
public function replace(array $input)
{
$this->getInputSource()->replace($input);
return $this;
}
/**
* Get the JSON payload for the request.
*
* @param string $key
* @param mixed $default
* @return \Symfony\Component\HttpFoundation\ParameterBag|mixed
*/
public function json($key = null, $default = null)
{
if (! isset($this->json)) {
$this->json = new ParameterBag((array) json_decode($this->getContent(), true));
}
if (is_null($key)) {
return $this->json;
}
return data_get($this->json->all(), $key, $default);
}
/**
* Get the input source for the request.
*
* @return \Symfony\Component\HttpFoundation\ParameterBag
*/
protected function getInputSource()
{
if ($this->isJson()) {
return $this->json();
}
return $this->getRealMethod() == 'GET' ? $this->query : $this->request;
}
/**
* Create an Illuminate request from a Symfony instance.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @return \Illuminate\Http\Request
*/
public static function createFromBase(SymfonyRequest $request)
{
if ($request instanceof static) {
return $request;
}
$content = $request->content;
$request = (new static)->duplicate(
$request->query->all(), $request->request->all(), $request->attributes->all(),
$request->cookies->all(), $request->files->all(), $request->server->all()
);
$request->content = $content;
$request->request = $request->getInputSource();
return $request;
}
/**
* {@inheritdoc}
*/
public function duplicate(array $query = null, array $request = null, array $attributes = null, array $cookies = null, array $files = null, array $server = null)
{
return parent::duplicate($query, $request, $attributes, $cookies, $this->filterFiles($files), $server);
}
/**
* Filter the given array of files, removing any empty values.
*
* @param mixed $files
* @return mixed
*/
protected function filterFiles($files)
{
if (! $files) {
return;
}
foreach ($files as $key => $file) {
if (is_array($file)) {
$files[$key] = $this->filterFiles($files[$key]);
}
if (empty($files[$key])) {
unset($files[$key]);
}
}
return $files;
}
/**
* Get the session associated with the request.
*
* @return \Illuminate\Session\Store
*
* @throws \RuntimeException
*/
public function session()
{
if (! $this->hasSession()) {
throw new RuntimeException('Session store not set on request.');
}
return $this->session;
}
/**
* Get the session associated with the request.
*
* @return \Illuminate\Session\Store|null
*/
public function getSession()
{
return $this->session;
}
/**
* Set the session instance on the request.
*
* @param \Illuminate\Contracts\Session\Session $session
* @return void
*/
public function setLaravelSession($session)
{
$this->session = $session;
}
/**
* Get the user making the request.
*
* @param string|null $guard
* @return mixed
*/
public function user($guard = null)
{
return call_user_func($this->getUserResolver(), $guard);
}
/**
* Get the route handling the request.
*
* @param string|null $param
*
* @return \Illuminate\Routing\Route|object|string
*/
public function route($param = null)
{
$route = call_user_func($this->getRouteResolver());
if (is_null($route) || is_null($param)) {
return $route;
}
return $route->parameter($param);
}
/**
* Get a unique fingerprint for the request / route / IP address.
*
* @return string
*
* @throws \RuntimeException
*/
public function fingerprint()
{
if (! $route = $this->route()) {
throw new RuntimeException('Unable to generate fingerprint. Route unavailable.');
}
return sha1(implode('|', array_merge(
$route->methods(), [$route->getDomain(), $route->uri(), $this->ip()]
)));
}
/**
* Set the JSON payload for the request.
*
* @param \Symfony\Component\HttpFoundation\ParameterBag $json
* @return $this
*/
public function setJson($json)
{
$this->json = $json;
return $this;
}
/**
* Get the user resolver callback.
*
* @return \Closure
*/
public function getUserResolver()
{
return $this->userResolver ?: function () {
//
};
}
/**
* Set the user resolver callback.
*
* @param \Closure $callback
* @return $this
*/
public function setUserResolver(Closure $callback)
{
$this->userResolver = $callback;
return $this;
}
/**
* Get the route resolver callback.
*
* @return \Closure
*/
public function getRouteResolver()
{
return $this->routeResolver ?: function () {
//
};
}
/**
* Set the route resolver callback.
*
* @param \Closure $callback
* @return $this
*/
public function setRouteResolver(Closure $callback)
{
$this->routeResolver = $callback;
return $this;
}
/**
* Get all of the input and files for the request.
*
* @return array
*/
public function toArray()
{
return $this->all();
}
/**
* Determine if the given offset exists.
*
* @param string $offset
* @return bool
*/
public function offsetExists($offset)
{
return array_key_exists(
$offset, $this->all() + $this->route()->parameters()
);
}
/**
* Get the value at the given offset.
*
* @param string $offset
* @return mixed
*/
public function offsetGet($offset)
{
return $this->__get($offset);
}
/**
* Set the value at the given offset.
*
* @param string $offset
* @param mixed $value
* @return void
*/
public function offsetSet($offset, $value)
{
$this->getInputSource()->set($offset, $value);
}
/**
* Remove the value at the given offset.
*
* @param string $offset
* @return void
*/
public function offsetUnset($offset)
{
$this->getInputSource()->remove($offset);
}
/**
* Check if an input element is set on the request.
*
* @param string $key
* @return bool
*/
public function __isset($key)
{
return ! is_null($this->__get($key));
}
/**
* Get an input element from the request.
*
* @param string $key
* @return mixed
*/
public function __get($key)
{
if (array_key_exists($key, $this->all())) {
return data_get($this->all(), $key);
}
return $this->route($key);
}
}
谢谢