Установил Yii2 на localhost, главная страница доступна по адресам http://localhost/web/site/index и http://localhost/web/ Включил ЧПУ, добавив в конфигурацию в файле app\config\web.php строки: PHP: 'urlManager' => [ 'enablePrettyUrl' => true, 'enableStrictParsing' => true, 'showScriptName' => false, 'rules' => [ ['class' => 'yii\rest\UrlRule', 'controller' => 'user'], ], ] Yii вообще не "подхватывается", голый экран с ошибкой 404 при попытке доступа: на http://localhost/users PHP: HTTP/1.1 404 Not Found Date: Fri, 08 May 2020 22:11:15 GMT Server: Apache/2.4.41 (Win64) PHP/7.4.1 Content-Length: 196 Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>404 Not Found</title> </head><body> <h1>Not Found</h1> <p>The requested URL was not found on this server.</p> </body></html> Также 404 ошибка отдается при попытке доступа на http://localhost/web/site/index В этом случае сам Yii2 подгружается: PHP: HTTP/1.1 404 Not Found Date: Fri, 08 May 2020 22:17:22 GMT Server: Apache/2.4.41 (Win64) PHP/7.4.1 X-Powered-By: PHP/7.4.1 Set-Cookie: PHPSESSID=grr3qdhuvjunhkiha9pbta7nh5; path=/; HttpOnly Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate Pragma: no-cache X-Debug-Tag: 5eb5da7214cd9 X-Debug-Duration: 46 X-Debug-Link: /web/debug/default/view?tag=5eb5da7214cd9 Set-Cookie: _csrf=d8c98373e08722801f7165aef549cd072201f6e8ea458c462375da8c0e2f9b5ea%3A2%3A%7Bi%3A0%3Bs%3A5%3A%22_csrf%22%3Bi%3A1%3Bs%3A32%3A%22Kem2akrdboCh5WcjXpzRhVOD21wS0k2p%22%3B%7D; path=/; HttpOnly Transfer-Encoding: chunked Content-Type: text/html; charset=UTF-8 Наличие/отсутствие .htaccess в корневой директории ни на что не повлияло. Всё делал по этому руководству - https://www.yiiframework.com/doc/guide/2.0/ru/rest-quick-start Насколько вижу, где-то сделал ошибку. Прошу подсказать, в чем ошибка.
Надо сделать локальный домен, натравленный на папку web --- Добавлено --- В доках есть конфиги и для апача, и для nginx-а, поищи --- Добавлено --- enableStrictParsing - это значит, отключить автоматическое распознавание урл как контроллер/акция, а позволять заходить только по урлам, прямо прописанным в конфиге
Спасибо за ответ. Указал в качестве корневой директории папку web, Yii "подхватывается", но обращение к http://localhost возвращает ошибку 404: Код (Text): curl -i -H "Accept:application/xml" "http://localhost" HTTP/1.1 404 Not Found Date: Sat, 09 May 2020 20:24:33 GMT Server: Apache/2.4.41 (Win64) PHP/7.4.1 X-Powered-By: PHP/7.4.1 Set-Cookie: PHPSESSID=ap134465v3lf133untkljt25lh; path=/; HttpOnly Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate Pragma: no-cache X-Debug-Tag: 5eb71181aa95d X-Debug-Duration: 51 X-Debug-Link: /debug/default/view?tag=5eb71181aa95d Set-Cookie: _csrf=285e741ea5303bf0213c31ef8823b9d8147178065aec833c94a6966fad50b35aa%3A2%3A%7Bi%3A0%3Bs%3A5%3A%22_csrf%22%3Bi%3A1%3Bs%3A32%3A%22P0VLjdB5OLLeIsY6D1rFYTo0vKrd1F6-%22%3B%7D; path=/; HttpOnly Transfer-Encoding: chunked Content-Type: text/html; charset=UTF-8 Обращение к http://localhost/users даёт ошибку 500: Код (Text): curl -i -H "Accept:application/xml" "http://localhost/users" HTTP/1.1 500 Internal Server Error Date: Sat, 09 May 2020 20:16:12 GMT Server: Apache/2.4.41 (Win64) PHP/7.4.1 X-Powered-By: PHP/7.4.1 Vary: Accept X-Debug-Tag: 5eb70f8cd6abf X-Debug-Duration: 35 X-Debug-Link: /debug/default/view?tag=5eb70f8cd6abf Content-Length: 1124 Connection: close Content-Type: application/xml; charset=UTF-8 <?xml version="1.0" encoding="UTF-8"?> <response><name>Exception</name><message>Call to undefined method app\models\User::find()</message><code>0</code><type>Error</type><file>E:\data\public\vendor\yiisoft\yii2\rest\IndexAction.php</file><line>114</line><stack-trace><item>#0 E:\data\public\vendor\yiisoft\yii2\rest\IndexAction.php(82): yii\rest\IndexAction->prepareDataProvider()</item><item>#1 [internal function]: yii\rest\IndexAction->run()</item><item>#2 E:\data\public\vendor\yiisoft\yii2\base\Action.php(94): call_user_func_array()</item><item>#3 E:\data\public\vendor\yiisoft\yii2\base\Controller.php(157): yii\base\Action->runWithParams()</item><item>#4 E:\data\public\vendor\yiisoft\yii2\base\Module.php(528): yii\base\Controller->runAction()</item><item>#5 E:\data\public\vendor\yiisoft\yii2\web\Application.php(103): yii\base\Module->runAction()</item><item>#6 E:\data\public\vendor\yiisoft\yii2\base\Application.php(386): yii\web\Application->handleRequest()</item><item>#7 E:\data\public\web\index.php(12): yii\base\Application->run()</item><item>#8 {main}</item></stack-trace></response> Правило 'controller'=>'user' прописано.
app\models\User: PHP: <?php namespace app\models; class User extends \yii\base\BaseObject implements \yii\web\IdentityInterface { public $id; public $username; public $password; public $authKey; public $accessToken; private static $users = [ '100' => [ 'id' => '100', 'username' => 'admin', 'password' => 'admin', 'authKey' => 'test100key', 'accessToken' => '100-token', ], '101' => [ 'id' => '101', 'username' => 'demo', 'password' => 'demo', 'authKey' => 'test101key', 'accessToken' => '101-token', ], ]; /** * {@inheritdoc} */ public static function findIdentity($id) { return isset(self::$users[$id]) ? new static(self::$users[$id]) : null; } /** * {@inheritdoc} */ public static function findIdentityByAccessToken($token, $type = null) { foreach (self::$users as $user) { if ($user['accessToken'] === $token) { return new static($user); } } return null; } /** * Finds user by username * * @param string $username * @return static|null */ public static function findByUsername($username) { foreach (self::$users as $user) { if (strcasecmp($user['username'], $username) === 0) { return new static($user); } } return null; } /** * {@inheritdoc} */ public function getId() { return $this->id; } /** * {@inheritdoc} */ public function getAuthKey() { return $this->authKey; } /** * {@inheritdoc} */ public function validateAuthKey($authKey) { return $this->authKey === $authKey; } /** * Validates password * * @param string $password password to validate * @return bool if password provided is valid for current user */ public function validatePassword($password) { return $this->password === $password; } } web.php: PHP: <?php $params = require __DIR__ . '/params.php'; $db = require __DIR__ . '/db.php'; $config = [ 'id' => 'basic', 'basePath' => dirname(__DIR__), 'bootstrap' => ['log'], 'aliases' => [ '@bower' => '@vendor/bower-asset', '@npm' => '@vendor/npm-asset', ], 'components' => [ 'request' => [ // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation 'cookieValidationKey' => 'a1TFc_oiNZ88_jThpbuyTO0OcmA3OC95', 'parsers' => [ 'application/json' => 'yii\web\JsonParser', ], // 'baseUrl' => '', ], 'cache' => [ 'class' => 'yii\caching\FileCache', ], 'user' => [ 'identityClass' => 'app\models\User', 'enableAutoLogin' => true, ], 'errorHandler' => [ 'errorAction' => 'site/error', ], 'mailer' => [ 'class' => 'yii\swiftmailer\Mailer', // send all mails to a file by default. You have to set // 'useFileTransport' to false and configure a transport // for the mailer to send real emails. 'useFileTransport' => true, ], 'log' => [ 'traceLevel' => YII_DEBUG ? 3 : 0, 'targets' => [ [ 'class' => 'yii\log\FileTarget', 'levels' => ['error', 'warning'], ], ], ], 'db' => $db, 'urlManager' => [ 'enablePrettyUrl' => true, 'enableStrictParsing' => true, 'showScriptName' => false, 'rules' => [ ['class' => 'yii\rest\UrlRule', 'controller' => 'user'], ], ], ], 'params' => $params, ]; if (YII_ENV_DEV) { // configuration adjustments for 'dev' environment $config['bootstrap'][] = 'debug'; $config['modules']['debug'] = [ 'class' => 'yii\debug\Module', // uncomment the following to add your IP if you are not connecting from localhost. //'allowedIPs' => ['127.0.0.1', '::1'], ]; $config['bootstrap'][] = 'gii'; $config['modules']['gii'] = [ 'class' => 'yii\gii\Module', // uncomment the following to add your IP if you are not connecting from localhost. //'allowedIPs' => ['127.0.0.1', '::1'], ]; } return $config; yiisoft\yii2\web\UrlManager.php (не менял ничего, вероятно, именно здесь соответствующие строки нужно было раскомментировать?) PHP: <?php /** * @link http://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC * @license http://www.yiiframework.com/license/ */ namespace yii\web; use Yii; use yii\base\Component; use yii\base\InvalidConfigException; use yii\caching\CacheInterface; use yii\di\Instance; use yii\helpers\Url; /** * UrlManager handles HTTP request parsing and creation of URLs based on a set of rules. * * UrlManager is configured as an application component in [[\yii\base\Application]] by default. * You can access that instance via `Yii::$app->urlManager`. * * You can modify its configuration by adding an array to your application config under `components` * as it is shown in the following example: * * ```php * 'urlManager' => [ * 'enablePrettyUrl' => true, * 'rules' => [ * // your rules go here * ], * // ... * ] * ``` * * Rules are classes implementing the [[UrlRuleInterface]], by default that is [[UrlRule]]. * For nesting rules, there is also a [[GroupUrlRule]] class. * * For more details and usage information on UrlManager, see the [guide article on routing](guide:runtime-routing). * * @property string $baseUrl The base URL that is used by [[createUrl()]] to prepend to created URLs. * @property string $hostInfo The host info (e.g. `http://www.example.com`) that is used by * [[createAbsoluteUrl()]] to prepend to created URLs. * @property string $scriptUrl The entry script URL that is used by [[createUrl()]] to prepend to created * URLs. * * @author Qiang Xue <qiang.xue@gmail.com> * @since 2.0 */ class UrlManager extends Component { /** * @var bool whether to enable pretty URLs. Instead of putting all parameters in the query * string part of a URL, pretty URLs allow using path info to represent some of the parameters * and can thus produce more user-friendly URLs, such as "/news/Yii-is-released", instead of * "/index.php?r=news%2Fview&id=100". */ public $enablePrettyUrl = false; /** * @var bool whether to enable strict parsing. If strict parsing is enabled, the incoming * requested URL must match at least one of the [[rules]] in order to be treated as a valid request. * Otherwise, the path info part of the request will be treated as the requested route. * This property is used only when [[enablePrettyUrl]] is `true`. */ public $enableStrictParsing = false; /** * @var array the rules for creating and parsing URLs when [[enablePrettyUrl]] is `true`. * This property is used only if [[enablePrettyUrl]] is `true`. Each element in the array * is the configuration array for creating a single URL rule. The configuration will * be merged with [[ruleConfig]] first before it is used for creating the rule object. * * A special shortcut format can be used if a rule only specifies [[UrlRule::pattern|pattern]] * and [[UrlRule::route|route]]: `'pattern' => 'route'`. That is, instead of using a configuration * array, one can use the key to represent the pattern and the value the corresponding route. * For example, `'post/<id:\d+>' => 'post/view'`. * * For RESTful routing the mentioned shortcut format also allows you to specify the * [[UrlRule::verb|HTTP verb]] that the rule should apply for. * You can do that by prepending it to the pattern, separated by space. * For example, `'PUT post/<id:\d+>' => 'post/update'`. * You may specify multiple verbs by separating them with comma * like this: `'POST,PUT post/index' => 'post/create'`. * The supported verbs in the shortcut format are: GET, HEAD, POST, PUT, PATCH and DELETE. * Note that [[UrlRule::mode|mode]] will be set to PARSING_ONLY when specifying verb in this way * so you normally would not specify a verb for normal GET request. * * Here is an example configuration for RESTful CRUD controller: * * ```php * [ * 'dashboard' => 'site/index', * * 'POST <controller:[\w-]+>' => '<controller>/create', * '<controller:[\w-]+>s' => '<controller>/index', * * 'PUT <controller:[\w-]+>/<id:\d+>' => '<controller>/update', * 'DELETE <controller:[\w-]+>/<id:\d+>' => '<controller>/delete', * '<controller:[\w-]+>/<id:\d+>' => '<controller>/view', * ]; * ``` * * Note that if you modify this property after the UrlManager object is created, make sure * you populate the array with rule objects instead of rule configurations. */ public $rules = []; // и т.д.
Сделал по этой инструкции, Yii2 корректно работает и обрабатывает ссылки в интерфейсе. Обращение к http://localhost/users продолжает возвращать 404: Код (Text): curl -i -H "Accept:application/xml" "http://localhost/users" HTTP/1.1 404 Not Found Date: Sun, 10 May 2020 11:31:46 GMT Server: Apache/2.4.41 (Win64) PHP/7.4.1 X-Powered-By: PHP/7.4.1 Set-Cookie: PHPSESSID=bfu1usjqt99kqtee49l5c47pqb; path=/; HttpOnly Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate Pragma: no-cache X-Debug-Tag: 5eb7e6221d249 X-Debug-Duration: 51 X-Debug-Link: /debug/default/view?tag=5eb7e6221d249 Set-Cookie: _csrf=cf4d6c0cb459f58d06c1fa7125a4bb84e3b44515ba0028f35a3ea02358f6c4e5a%3A2%3A%7Bi%3A0%3Bs%3A5%3A%22_csrf%22%3Bi%3A1%3Bs%3A32%3A%22wPRgA94sr1YAIeps8_R_v__WrPjTcR8m%22%3B%7D; path=/; HttpOnly Transfer-Encoding: chunked Content-Type: text/html; charset=UTF-8
Ну чтоб вызывать User::find(), User должен быть унаследован от ActiveRecord, а не BaseObject, это раз. Просто базовый шаблон приложения из коробки поставляется с примером аутентификации без БД. https://www.yiiframework.com/doc/api/2.0/yii-rest-urlrule В конроллере нужные методы есть? Вообще, странно. Ну я понимаю, с Laravel тут у многих проблемы, потому что английский никто нифига не учит. Ну у yii2 большая часть документации есть и на русском, в чём проблема внимательно прочитать её от корки до корки?
Контроллер app\controllers\UserController.php из примера в документации. Больше в нём нет ничего. PHP: namespace app\controllers; use yii\rest\ActiveController; class UserController extends ActiveController { public $modelClass = 'app\models\User'; } С изучением Laravel больших проблем не возникло, многие вещи, читаемые в русскоязычной документации по Yii2, понимал только потому, что ранее это понял в Laravel. А вот тут уперся при выполнении примера из документации на этой странице.