teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

15

修正

2019/04/07 09:57

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -25,20 +25,20 @@
25
25
  $route = $request->route();
26
26
  $lang = $route->parameter('lang');
27
27
 
28
+ if ($lang !== null) {
29
+
28
- // デフォルトロケールまたは存在しないロケールならフォールバック
30
+ // デフォルトロケールまたは存在しないロケールならフォールバック
29
- if (
31
+ if (
30
- $lang !== null
31
- && (
32
32
  $lang === config('app.fallback_locale')
33
33
  || !in_array($lang, $this->possibleLocales, true)
34
- )
35
- ) {
34
+ ) {
36
- return redirect()->route(substr($route->getName(), 5));
35
+ return redirect()->route(substr($route->getName(), 5));
36
+ }
37
+
38
+ // ロケールの設定
39
+ App::setLocale($lang);
37
40
  }
38
41
 
39
- // ロケールの設定
40
- App::setLocale($lang);
41
-
42
42
  return $next($request);
43
43
  }
44
44
  }

14

修正

2019/04/07 09:57

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -27,8 +27,11 @@
27
27
 
28
28
  // デフォルトロケールまたは存在しないロケールならフォールバック
29
29
  if (
30
+ $lang !== null
31
+ && (
30
- $lang === config('app.fallback_locale')
32
+ $lang === config('app.fallback_locale')
31
- || !in_array($lang, $this->possibleLocales, true)
33
+ || !in_array($lang, $this->possibleLocales, true)
34
+ )
32
35
  ) {
33
36
  return redirect()->route(substr($route->getName(), 5));
34
37
  }

13

フォールバック設定

2019/04/07 09:56

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -18,14 +18,24 @@
18
18
  ```php
19
19
  class LocaleMiddleware
20
20
  {
21
+ protected $possibleLocales = ['ja', 'en', 'cn', 'ru'];
22
+
21
23
  public function handle(Request $request, Closure $next)
22
24
  {
25
+ $route = $request->route();
23
- $lang = $request->route('lang');
26
+ $lang = $route->parameter('lang');
24
27
 
28
+ // デフォルトロケールまたは存在しないロケールならフォールバック
25
- if ($lang) {
29
+ if (
26
- App::setLocale($lang);
30
+ $lang === config('app.fallback_locale')
31
+ || !in_array($lang, $this->possibleLocales, true)
32
+ ) {
33
+ return redirect()->route(substr($route->getName(), 5));
27
34
  }
28
35
 
36
+ // ロケールの設定
37
+ App::setLocale($lang);
38
+
29
39
  return $next($request);
30
40
  }
31
41
  }

12

修正

2019/04/07 09:55

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -60,9 +60,7 @@
60
60
  $params['lang'] += App::getLocale();
61
61
 
62
62
  return route(
63
- $params['lang'] === config('app.fallback_locale')
63
+ $params['lang'] === config('app.fallback_locale') ? $name : "lang.$name",
64
- ? $name
65
- : "$params[lang].$name",
66
64
  $params
67
65
  );
68
66
  }

11

リファクタ

2019/04/07 09:41

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -57,11 +57,13 @@
57
57
  ```php
58
58
  function route_i18n(string $name, array $params): string
59
59
  {
60
- $lang = $params['lang'] ?? App::getLocale();
60
+ $params['lang'] += App::getLocale();
61
61
 
62
62
  return route(
63
- $lang === config('app.fallback_locale') ? $name : "$lang.$name",
63
+ $params['lang'] === config('app.fallback_locale')
64
+ ? $name
64
- $params + compact('lang')
65
+ : "$params[lang].$name",
66
+ $params
65
67
  );
66
68
  }
67
69
  ```

10

修正

2019/04/07 09:40

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -78,4 +78,6 @@
78
78
 
79
79
  ----
80
80
 
81
- これで `route_i18n` を使って定義するのはどうでしょうか?現在表示しているページの言語にあったルーティングを暗黙的に書けます。言語を切り替えるときもそれを `$params` に渡せば、引数のほうが優先されるので問題ありません。
81
+ これで `route_i18n` を使って定義するのはどうでしょうか?現在表示しているページの言語にあったルーティングを暗黙的に書けます。言語を切り替えるときもそれを `$params` に渡せば、引数のほうが優先されるので問題ありません。
82
+
83
+ 中身の多言語化に関しては通常どおり `__` 関数を使うだけですね。とても簡単です。

9

修正

2019/04/07 09:36

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -60,7 +60,7 @@
60
60
  $lang = $params['lang'] ?? App::getLocale();
61
61
 
62
62
  return route(
63
- $lang === config('fallback_locale') ? $name : "$lang.$name",
63
+ $lang === config('app.fallback_locale') ? $name : "$lang.$name",
64
64
  $params + compact('lang')
65
65
  );
66
66
  }

8

リファクタ

2019/04/07 09:33

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -11,42 +11,71 @@
11
11
 
12
12
  が原因かと思われます。
13
13
 
14
- # 対策
14
+ # 実装方針
15
15
 
16
- 以下のようなヘルパー関数を適当な場所に定義してください。`app/helpers.php` を作って composer.json `autoload` の `files` に書くのがおすすめです。
16
+ #### ミドルウェア作成
17
17
 
18
- ```
18
+ ```php
19
+ class LocaleMiddleware
19
20
  {
20
- "autoload": {
21
+ public function handle(Request $request, Closure $next)
22
+ {
21
- "files": ["app/helpers.php"]
23
+ $lang = $request->route('lang');
24
+
25
+ if ($lang) {
26
+ App::setLocale($lang);
27
+ }
28
+
29
+ return $next($request);
22
30
  }
23
31
  }
24
32
  ```
25
33
 
26
- ```php
34
+ #### ルーティング定義
27
- function route_i18n(string $name, array $params): string
28
- {
29
- $lang = $params['lang'] ?? request()->route('lang');
30
35
 
31
- return route(
36
+ ルーティング定義は以下のようになります。
32
- $lang ? $name : "$lang.$name",
33
- $lang ? $params + compact('lang') : $params
34
- );
35
- }
36
- ```
37
37
 
38
- ルーティング定義は以下のようになります。アプリケーションの実際の定義は `routes/localized.php` に書いてください。
39
-
40
38
  ```php
41
39
  // デフォルト言語
42
40
  Route::namespace('App\Http\Controllers')
43
41
  ->group(base_path('routes/localized.php'));
44
42
 
45
43
  // 各言語
44
+ Route::namespace('App\Http\Controllers')
45
+ ->middleware(LocaleMiddleware::class)
46
- Route::prefix('{lang}')
46
+ ->prefix('{lang}')
47
47
  ->as('lang.')
48
- ->namespace('App\Http\Controllers')
49
48
  ->group(base_path('routes/localized.php'));
50
49
  ```
51
50
 
51
+ アプリケーションの実際の定義は `routes/localized.php` に書いてください。
52
+
53
+ #### ヘルパー関数の作成
54
+
55
+ 以下のようなヘルパー関数を適当な場所に定義してください。
56
+
57
+ ```php
58
+ function route_i18n(string $name, array $params): string
59
+ {
60
+ $lang = $params['lang'] ?? App::getLocale();
61
+
62
+ return route(
63
+ $lang === config('fallback_locale') ? $name : "$lang.$name",
64
+ $params + compact('lang')
65
+ );
66
+ }
67
+ ```
68
+
69
+ `app/helpers.php` を作って composer.json の `autoload` の `files` に書くのがおすすめです。
70
+
71
+ ```
72
+ {
73
+ "autoload": {
74
+ "files": ["app/helpers.php"]
75
+ }
76
+ }
77
+ ```
78
+
79
+ ----
80
+
52
81
  これで `route_i18n` を使って定義するのはどうでしょうか?現在表示しているページの言語にあったルーティングを暗黙的に書けます。言語を切り替えるときもそれを `$params` に渡せば、引数のほうが優先されるので問題ありません。

7

まとめ

2019/04/07 09:31

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -1,31 +1,28 @@
1
- 質問文から判断する限りではメソッド引数に何も影響は無いように思います。`$lang` は受け取ることもできますが、受け取らなくてもいいはず。
1
+ # 概要
2
2
 
3
- ---
3
+ エラーが出る原因は
4
4
 
5
- ```php
6
- Route::prefix('{lang}')
5
+ - ルーティングされるメソッドに `$lang` が定義されていない
6
+
7
+ からではなく
8
+
7
- ->namespace('App\Http\Controllers')
9
+ - ルーティングリンク生成時に `{lang}` が含まれるほうを利用している
8
- ->group(function () {
9
- Route::get('example', 'ExampleController@index');
10
+ - にも関わらず、`["lang" => $lang]` をパラメータに渡していない
11
+
12
+ が原因かと思われます。
13
+
10
- });
14
+ # 対策
15
+
16
+ 以下のようなヘルパー関数を適当な場所に定義してください。`app/helpers.php` を作って composer.json の `autoload` の `files` に書くのがおすすめです。
17
+
11
18
  ```
12
-
13
- ```php
14
- class ExampleController extends Controller
15
19
  {
16
- public function index()
20
+ "autoload": {
17
- {
18
- return 'working fine';
21
+ "files": ["app/helpers.php"]
19
22
  }
20
23
  }
21
24
  ```
22
25
 
23
- これで `/en/example` でアクセスして動きました
24
-
25
- ----
26
-
27
- ヘルパー関数↓
28
-
29
26
  ```php
30
27
  function route_i18n(string $name, array $params): string
31
28
  {
@@ -38,7 +35,7 @@
38
35
  }
39
36
  ```
40
37
 
41
- ルーティング定義実際の定義は `routes/localized.php` に書く)↓
38
+ ルーティング定義は以下のようになります。アプリケーションの実際の定義は `routes/localized.php` に書いてださい。
42
39
 
43
40
  ```php
44
41
  // デフォルト言語

6

訂正

2019/04/07 09:14

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -30,9 +30,11 @@
30
30
  function route_i18n(string $name, array $params): string
31
31
  {
32
32
  $lang = $params['lang'] ?? request()->route('lang');
33
- $route = $lang ? $name : "$lang.$name";
34
33
 
34
+ return route(
35
+ $lang ? $name : "$lang.$name",
35
- return route($route, $params + compact('lang'));
36
+ $lang ? $params + compact('lang') : $params
37
+ );
36
38
  }
37
39
  ```
38
40
 

5

訂正

2019/04/07 09:07

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -30,11 +30,9 @@
30
30
  function route_i18n(string $name, array $params): string
31
31
  {
32
32
  $lang = $params['lang'] ?? request()->route('lang');
33
-
34
33
  $route = $lang ? $name : "$lang.$name";
35
- $params += $lang ? compact('lang') : [];
36
34
 
37
- return route($route, $params);
35
+ return route($route, $params + compact('lang'));
38
36
  }
39
37
  ```
40
38
 

4

訂正

2019/04/07 09:03

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -29,7 +29,7 @@
29
29
  ```php
30
30
  function route_i18n(string $name, array $params): string
31
31
  {
32
- $lang = request()->route('lang');
32
+ $lang = $params['lang'] ?? request()->route('lang');
33
33
 
34
34
  $route = $lang ? $name : "$lang.$name";
35
35
  $params += $lang ? compact('lang') : [];

3

修正

2019/04/07 09:01

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -52,4 +52,4 @@
52
52
  ->group(base_path('routes/localized.php'));
53
53
  ```
54
54
 
55
- これで `route_i18n` を使って定義するのはどうでしょうか?
55
+ これで `route_i18n` を使って定義するのはどうでしょうか?現在表示しているページの言語にあったルーティングを暗黙的に書けます。言語を切り替えるときもそれを `$params` に渡せば、引数のほうが優先されるので問題ありません。

2

編集

2019/04/07 09:00

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -20,4 +20,36 @@
20
20
  }
21
21
  ```
22
22
 
23
- これで `/en/example` でアクセスして動きました
23
+ これで `/en/example` でアクセスして動きました
24
+
25
+ ----
26
+
27
+ ヘルパー関数↓
28
+
29
+ ```php
30
+ function route_i18n(string $name, array $params): string
31
+ {
32
+ $lang = request()->route('lang');
33
+
34
+ $route = $lang ? $name : "$lang.$name";
35
+ $params += $lang ? compact('lang') : [];
36
+
37
+ return route($route, $params);
38
+ }
39
+ ```
40
+
41
+ ルーティング定義(実際の定義は `routes/localized.php` に書く)↓
42
+
43
+ ```php
44
+ // デフォルト言語
45
+ Route::namespace('App\Http\Controllers')
46
+ ->group(base_path('routes/localized.php'));
47
+
48
+ // 各言語
49
+ Route::prefix('{lang}')
50
+ ->as('lang.')
51
+ ->namespace('App\Http\Controllers')
52
+ ->group(base_path('routes/localized.php'));
53
+ ```
54
+
55
+ これで `route_i18n` を使って定義するのはどうでしょうか?

1

2019/04/07 08:58

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -1,1 +1,23 @@
1
- 質問文から判断する限りではメソッド引数に何も影響は無いように思います。`$lang` は受け取ることもできますが、受け取らなくてもいいはず。
1
+ 質問文から判断する限りではメソッド引数に何も影響は無いように思います。`$lang` は受け取ることもできますが、受け取らなくてもいいはず。
2
+
3
+ ---
4
+
5
+ ```php
6
+ Route::prefix('{lang}')
7
+ ->namespace('App\Http\Controllers')
8
+ ->group(function () {
9
+ Route::get('example', 'ExampleController@index');
10
+ });
11
+ ```
12
+
13
+ ```php
14
+ class ExampleController extends Controller
15
+ {
16
+ public function index()
17
+ {
18
+ return 'working fine';
19
+ }
20
+ }
21
+ ```
22
+
23
+ これで `/en/example` でアクセスして動きました