关于 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
)
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
最佳答案

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)

5年前 评论
李小明 4年前
宋高峰 3年前
讨论数量: 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)

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

@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 類型

5年前 评论

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)

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

@leochien @FMW

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

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

5年前 评论

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

5年前 评论
LoCarlu 2年前

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

file

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

file

5年前 评论

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

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!