简体   繁体   English

如何获取在PHP中作为参数传递的变量名?

[英]How to get a variable name that's been passed as an argument in PHP?

I have a view method that accepts 2 arguments, one of them is the data for that view. 我有一个接受2个参数的view方法,其中一个是该视图的数据。 I have it set as $data as the methods argument. 我将其设置为$data作为方法参数。

I'm using the class as follows: 我正在使用以下类:

view->make('testview', $movies);

In this case $movies is an object, but it could be just text. 在这种情况下, $movies是一个对象,但也可能只是文本。

class View {

    public function make($view, $data) {
        require_once("../app/views/$view" . ".php");
        var_dump($data);
    }

}

The thing is, I don't want to use $data->whatever() in all my views because this has no semantic meaning and makes it difficult to review. 问题是,我不想在所有视图中都使用$data->whatever() ,因为这没有语义含义,并且很难进行检查。 I would like my view data to have the same name as the variable that I pass to it. 我希望我的视图数据与传递给它的变量具有相同的名称。 In this case I passed the variable $movies to it, so I want to be able to use $movies->whatever() in my view. 在这种情况下,我将变量$movies传递给它,因此我希望能够在我的视图中使用$movies->whatever()

In essence I want the variable that I pass to the method to keep the same variable name and be usable like that within the function. 从本质上讲,我希望传递给方法的变量保持相同的变量名称,并像在函数中一样可用。

How do I do this? 我该怎么做呢?

You cannot get the name of the variable in the call. 您无法在调用中获取变量的名称。 What you can do is alike to what template-engines do in this case: do not just assign a variable, but assign it to something. 在这种情况下,您可以做的事情与模板引擎相似:不仅分配变量,还要将其分配给某些东西。

So you would, for instance 因此,例如

$view = new View();
$view->assign('movies', $movies);
$view->make('testview');

in the assign function you have both the content and the name, so you could make a variable with that name. assign函数中,您同时拥有内容和名称,因此可以使用该名称创建变量。 There's probably a better fix then this, but this can get you started: 可能有一个更好的解决方案,但这可以帮助您入门:

function assign($name, $data)
{
    $$name = $data;
    //now you have a $movies in your template
}

This is not a very solid sollution, especially the way you have to require that view. 这不是一个非常可靠的解决方案,尤其是您需要该视图的方式。 There are many functions you might need to add to get this going, and these are implemented in the more default templating frameworks like eg smarty . 为此,可能需要添加许多功能,并且这些功能是在更默认的模板框架中实现的,例如smarty Take a look if that is something for you, it sounds like you want to create something like that. 看一下这是否适合您,听起来您想创建类似的东西。

If it's just the name you want to keep track of, you could keep the original $data parameter name but default it to use an array. 如果只是要跟踪的名称,则可以保留原始的$ data参数名称,但默认情况下使用数组。 You would pass the function array('movies'=>$movies) (or array('gerbils'=>$gerbils) if you want) for the $data parameter. 您将为$ data参数传递函数array('movies'=>$movies) (或array('gerbils'=>$gerbils) )。 That would allow you to keep track of the original variable name without implementing a bunch of extra functions, but you'd have to use $data['movies'] syntax to access it. 这将允许您跟踪原始变量名,而无需实现大量额外功能,但是您必须使用$data['movies']语法来访问它。 This has the advantage of being less confusing to future developers who may need to look at your code, too. 这样做的好处是,对将来可能需要查看您的代码的开发人员也不会造成混淆。

Although you can get the function's argument names dynamically, I think it is not possible to get the passing variable names. 尽管可以动态获取函数的参数名称 ,但我认为无法获取传递的变量名称。 Alternatively you could just pass one argument of associate array and extract it in the function. 或者,您可以仅传递关联数组的一个参数并将其提取到函数中。

$param = array(
    'view' => 'testview',
    'movies' => $movies
);
view->make($param);

You could then extract the arguments in the make function. 然后,您可以在make函数中提取参数。

class View {

    public function make($arg) {
        extract($arg);
        // now you get
        // $view
        // $movies
        require_once("../app/views/$view" . ".php");
        var_dump($movies);
    }
}

Nonetheless, I'm not sure why you want to use $movies or something else in the called function since I guess you want it dynamic and automate. 但是,我不确定为什么要在调用的函数中使用$movies或其他内容,因为我想您希望它是动态且自动化的。

What you could do is to pass an array and extract() it within your make() method. 您可以做的是在make()方法中传递一个数组并将其extract() So the contents of the passed array will be available as variables in the current symbol table. 因此,所传递数组的内容将在当前符号表中用作变量。

<?php

// Controller or something

$movies = [
    ['name' => 'Fight Club' => 'rating' => 'great'],
    ['name' => 'The Avengers', 'rating' => 'great'],
    ['name' => 'Iron Man 2',   'rating' => 'sucks'],
];

view->make('testview', compact('movies'));

// View Class

class View {

    public function make($view, $data) {
        extract($data);

        //Usage in Viewfile: $movies[0]['name']
        require_once("../app/views/$view" . ".php");
    }

}

Of course the contents of the passed array do not matter, so you can easily pass around objects, or other things. 当然,传递的数组的内容无关紧要,因此您可以轻松地传递对象或其他内容。

Just as an alternative: if you're using objects for all your data types, and you want to deal with just a single parameter in your method call, you could assign the name of the variable based on the type of object received. 另一个选择是: 如果您对所有数据类型都使用对象,并且只想在方法调用中处理单个参数,则可以根据接收到的对象的类型分配变量的名称。

class View {

    public function make($object) {

        //if it's an object - use the type of object to define the variable
        if(is_object($object)) {

            switch(get_class($object)) {

                case 'Movie':
                    $movie = $object;
                    break;

                case 'CD'
                    $cd = $object;
                    break;

                // ... and so on

                default:
                    $data = $object;
                    break;
            }
        }

        //otherwise go with a default of $data
        else {
            $data = $object;
        }
    }

}

I'd personally feel the need to validate the variable with isset() in every view file though, just in case the wrong type of object was passed in - and I fear it would end up with far more validation required in all the view files than necessary. 我个人觉得需要在每个视图文件中使用isset()来验证变量,以防万一传入了错误类型的对象-我担心最终将需要在所有视图文件中进行更多的验证超过必要。


To go one step further 更进一步

Alternatively your classes could all extend a common (abstract) class which can hold the type - set that type in the constructor of all your sub-classes and determine the variable name based upon that (set the parent's protected $type; with $this->type = 'movie'; inside the Movie constructor for instance). 或者,您的类都可以扩展一个通用的(抽象的)类,该类可以容纳该类型 -在所有子类的构造函数中设置该类型,然后根据该值确定变量名(设置父级protected $type;使用$this->type = 'movie';例如在Movie构造函数中)。

This would give you something like this (note: ${$object->getType()} = $object; ) which works but I'm not sure about the sanity of it: 这会给你这样的东西(注意: ${$object->getType()} = $object; )可以工作,但是我不确定它的合理性:

class View {

    public function make($object) {

        //if it's an object - use the type of object to define the variable
        //  so for the `Movie` object where the type is 'movie' this will
        //  create a variable called $movie containing the Movie object
        if(is_object($object) && method_exists($object, 'getType')) {

            ${$object->getType()} = $object;
            require_once "/path/to/{$object->getType()}.php";
        }
    }
}

/**
 * base abstract 'thing'
 */
abstract class Thing {

    protected $type;

    public function getType() {
        return $this->type;
    }

}

/**
 * a Movie 'thing'
 */
class Movie extends Thing {

    public function __construct() {
        $this->type = 'movie';
    }

}

//processing stuff
$oView = new View();
$oView->make( new Movie() );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM