关于 compact ('user') 中使用'user'的疑问?

问题#

请问各位:#

  1. 教程里面的下段代码中,edit() 方法传入的实例是 $user,而在调用 compact() 处理时,用的是 'user' 而不是 $user。对此,我查了下 PHP 的手册,手册的范例中用 'var'$var 都可以传入参数(见最下方范例),但是把教程中的 'user' 换成 $user 却无法得到 相同的结果。
    且经过试验,在 return view('users.edit', compact('something')); 这行代码里面,必须用 'something' 来传入参数,而不能用 $something,这是否由于处于 view() 里面呢,有没有相关的解释或原理资料?
  2. compact() 函数应该返回一个 array 对象,但在 view 中用 {{var_dump($user)}} 查看 $user 变量的详情时,显示的类型是 object(App\Models\User),这是 Laravel 框架特有的性质吗?应该怎样理解呢?

    谢谢分享和解答。#

<?php
namespace App\Http\Controllers;
.
.
.
class UsersController extends Controller
{
    .
    .
    .
    public function edit(User $user)
    {
        return view('users.edit', compact('user'));
    }
}

PHP 手册的范例 ¶#

Example #1 compact () 例子#

<?php
$city  = "San Francisco";
$state = "CA";
$event = "SIGGRAPH";

$location_vars = array("city", "state");

$result = compact("event", "nothing_here", $location_vars);
print_r($result);
?>

以上例程会输出:

Array
(
    [event] => SIGGRAPH
    [city] => San Francisco
    [state] => CA
)
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
最佳答案

1. 为什么 user 可以,而 $user 不可以?

先看下 PHP 官方对于这个函数的解释。

对每个参数,compact () 在当前的符号表中查找该变量名并将它添加到输出的数组中,变量名成为键名而变量的内容成为该键的值。

意思就是,PHP 会根据传入的参数,去从当前的符号表,也就是 compact 所执行的作用域去寻找有没有相应名称的变量,所以 edit() 方法传入的是 $user,但是 $user 并不是 $user 这个变量的名称,user 才是,$ 是 PHP 对变量的一种标识吧,看下 PHP 对变量的解释。

PHP 中的变量用一个美元符号后面跟变量名来表示。变量名是区分大小写的。

所以 user 才是变量名,而不是 $user。所以你传入 $user,自然就找不到名为 $user 的变量。

延伸:从某种意义上来说,$user 这种变量名是不存在的。PHP 有一个可变变量的概念,$$user 所表示的意义是,访问变量名称为 $user 内容的变量,也就是如果 $user 的内容是 job,那么 $$user 访问的变量就是 $job,如果 user 变量没有定义的话,程序就会报错了。

2. 为什么 user 变量的类型是 object(App\Models\User),而不是 array

因为 view() 函数的第二个参数就是你要传进视图的数据。这个参数是一个数组,也就是这个数组里的数据都是要传入视图的。如下对比代码所示:

public function edit(User $user)
{
    return view('users.edit', compact('user'));
}

等于

public function edit(User $user)
{
    return view('users.edit', [
        'user' => $user
    ]);
}

所以你在视图里访问 user 变量的时候,实际访问的就是这个数组里 user 键所对应的内容,也就是 edit 函数传进来的 user 参数,这个 user 参数就是框架自动注入进来的 User 模型的实例,所以这个变量的类型显然就是 object(App\Models\User)

7年前 评论
李小明 5年前
宋高峰 4年前
讨论数量: 11

1. 为什么 user 可以,而 $user 不可以?

先看下 PHP 官方对于这个函数的解释。

对每个参数,compact () 在当前的符号表中查找该变量名并将它添加到输出的数组中,变量名成为键名而变量的内容成为该键的值。

意思就是,PHP 会根据传入的参数,去从当前的符号表,也就是 compact 所执行的作用域去寻找有没有相应名称的变量,所以 edit() 方法传入的是 $user,但是 $user 并不是 $user 这个变量的名称,user 才是,$ 是 PHP 对变量的一种标识吧,看下 PHP 对变量的解释。

PHP 中的变量用一个美元符号后面跟变量名来表示。变量名是区分大小写的。

所以 user 才是变量名,而不是 $user。所以你传入 $user,自然就找不到名为 $user 的变量。

延伸:从某种意义上来说,$user 这种变量名是不存在的。PHP 有一个可变变量的概念,$$user 所表示的意义是,访问变量名称为 $user 内容的变量,也就是如果 $user 的内容是 job,那么 $$user 访问的变量就是 $job,如果 user 变量没有定义的话,程序就会报错了。

2. 为什么 user 变量的类型是 object(App\Models\User),而不是 array

因为 view() 函数的第二个参数就是你要传进视图的数据。这个参数是一个数组,也就是这个数组里的数据都是要传入视图的。如下对比代码所示:

public function edit(User $user)
{
    return view('users.edit', compact('user'));
}

等于

public function edit(User $user)
{
    return view('users.edit', [
        'user' => $user
    ]);
}

所以你在视图里访问 user 变量的时候,实际访问的就是这个数组里 user 键所对应的内容,也就是 edit 函数传进来的 user 参数,这个 user 参数就是框架自动注入进来的 User 模型的实例,所以这个变量的类型显然就是 object(App\Models\User)

7年前 评论
李小明 5年前
宋高峰 4年前

@siranzhong

<?php
$city  = "San Francisco";
$state = "CA";
$event = "SIGGRAPH";

$location_vars = array("city", "state");

$result = compact("event", "nothing_here", $location_vars);
print_r($result);

Array
(
    [event] => SIGGRAPH
    [city] => San Francisco
    [state] => CA
)
?>

從這段 Code 可以看出,compact 的作用是讀入變量名,並將對應的變量值輸出成 Array
之所以能傳入 $location_vars 這個參數,是因為 $location_vars 中的 city 及 state 已經在上面宣吿
所以你的 $user 裡面並不包含已宣告的變量名,自然沒辦法被 compact 讀入

至於為什麼 $user 會是 Object 類型,可以參考 Collection 文件,因 Collection 本身是 Object 類型,Eloquent Model 又是繼承 Collection,所以你的 User Model 也會是跟 Collection 一樣的 Object 類型

7年前 评论

1. 为什么 user 可以,而 $user 不可以?

先看下 PHP 官方对于这个函数的解释。

对每个参数,compact () 在当前的符号表中查找该变量名并将它添加到输出的数组中,变量名成为键名而变量的内容成为该键的值。

意思就是,PHP 会根据传入的参数,去从当前的符号表,也就是 compact 所执行的作用域去寻找有没有相应名称的变量,所以 edit() 方法传入的是 $user,但是 $user 并不是 $user 这个变量的名称,user 才是,$ 是 PHP 对变量的一种标识吧,看下 PHP 对变量的解释。

PHP 中的变量用一个美元符号后面跟变量名来表示。变量名是区分大小写的。

所以 user 才是变量名,而不是 $user。所以你传入 $user,自然就找不到名为 $user 的变量。

延伸:从某种意义上来说,$user 这种变量名是不存在的。PHP 有一个可变变量的概念,$$user 所表示的意义是,访问变量名称为 $user 内容的变量,也就是如果 $user 的内容是 job,那么 $$user 访问的变量就是 $job,如果 user 变量没有定义的话,程序就会报错了。

2. 为什么 user 变量的类型是 object(App\Models\User),而不是 array

因为 view() 函数的第二个参数就是你要传进视图的数据。这个参数是一个数组,也就是这个数组里的数据都是要传入视图的。如下对比代码所示:

public function edit(User $user)
{
    return view('users.edit', compact('user'));
}

等于

public function edit(User $user)
{
    return view('users.edit', [
        'user' => $user
    ]);
}

所以你在视图里访问 user 变量的时候,实际访问的就是这个数组里 user 键所对应的内容,也就是 edit 函数传进来的 user 参数,这个 user 参数就是框架自动注入进来的 User 模型的实例,所以这个变量的类型显然就是 object(App\Models\User)

7年前 评论
李小明 5年前
宋高峰 4年前

@leochien @FMW

感谢两位花时间详细解答。结合两位的回复,我已经有个模糊的概念,但是对涉及的底层机制,以目前的水平还没有完全理解。为了不卡壳,还是决定继续沿着教程用起来,以后等级够了再回头思考吧。
由于还没完全弄懂,在选择答案时, 只能以篇幅长短为依据了,望见谅。
7年前 评论

@FMW 大的回答太詳細,連我都把之前有點模糊的概念搞懂了?

7年前 评论

@leochien 也就是说 compact () 不仅可以读字符串形式的变量名,也可以读索引数组的键值得所有变量名。不知道我的理解对不对。

6年前 评论
LoCarlu 3年前

我不明白楼主为什么会有这样的疑问
1. 首先为什么不能直接使用 $user compact ($user) 因为 $user 是一个变量 而不是一个变量名数组 请看下图
楼主的截图中其实已经说明了答案

file

2. 那我就是想和上图一样使用变量名 compact ($user) 怎么办?
答:创建一个变量名数组把 $user 放进去即可

file

6年前 评论

$user 是个对象,compact 要的是个字符串,

5年前 评论