找到调用var的名称

时间:2010-02-02 12:57:42

标签: php

任何人都知道PHP是否可以实现这一点?

function foo($var) {
    // the code here should output the value of the variable
    // and the name the variable has when calling this function
}

$hello = "World";
foo($hello);

会给我这个输出

varName = $hello
varValue = World

修改

由于这里的大多数人“指责”我的不良行为和全局变量,我将进一步详细阐述我们为什么要寻找这种行为。

我们正在考虑这种行为的原因是我们希望更容易为视图分配变量。

大部分时间我们这样做是为我们的视图分配变量

$this->view->assign('products', $products);
$this->view->assign('members', $members);

虽然只是能够执行以下操作并让视图负责确定变量名称,所以分配的数据会在我们的视图中显示,这样会更容易和更具可读性。

$this->view->assign($products);
$this->view->assign($members);

10 个答案:

答案 0 :(得分:5)

简答:不可能。

答案很长:您可以浏览apdbytekitrunkitReflection APIdebug_backtrace,看看是否有任何模糊的组合可以让您实现这种行为。

但是,最简单的方法是简单地将变量名称与实际变量一起传递,就像您已经做的那样。它简短,易于掌握,当您需要变量具有不同的名称并且方式更快时,它比任何可能实现其他所需行为的可能代码更灵活。

保持简单

OP编辑问题后,

删除了不相关的部分

答案 1 :(得分:4)

无论我怀疑这是否可能,我认为强迫程序员如何命名他的变量通常是一个坏主意。你必须回答像

这样的问题
  

为什么我不能将变量命名为$arrProducts而不是$products

如果要将函数的返回值放入视图中,也会遇到严重问题。想象一下以下代码,其中(无论出于何种原因)该类别必须是小写的:

$this->view->assign(strtolower($category)); 

这不符合您的计划。

我的答案是:坚持你工作的'冗长'方式,阅读和维护更容易。

如果你不能忍受,你仍然可以在视图中添加magic function

public function __set($name, $value) {
    $this->assign($name, $value);
}

然后你可以写

$this->view->product = $product;

答案 2 :(得分:2)

我认为没有任何语言可以实现。这根本不是变量的工作原理。变量与其拥有的值之间存在差异。在函数foo内,您有值,但保存该值的变量不可用。相反,您有一个新变量$var来保存该值。

这样看:变量就像一个带有名字的桶。变量的内容(值)就是桶内的内容。当你调用一个函数时,它会带有自己的桶(参数名称),然后你将桶的内容倒入那些(好吧,这里的比喻因为价值被复制而仍在外面可用)。在函数内部,无法知道用于保存内容的存储桶。

答案 3 :(得分:2)

你所要求的是不可能的。即使它是,它也可能被认为是不好的做法,因为它很容易被利用。

如果您决定实现这样的目标,那么最接近的就是将变量名称作为字符串传递,并在$ GLOBALS数组的函数中引用它。

例如

function this_aint_a_good_idea_really($var) {
    print "Variable name: {$var}\n";
    print "Variable contents: {$GLOBALS[$var]}\n";
}
$hello="World";
this_aint_a_good_idea_really('hello');

但正如我所说,这不是一个好主意,也不是非常有用。 (坦率地说,几乎在你使用全局变量时,你可能做错了什么)

答案 4 :(得分:1)

这不是不可能的,您可以找到从debug_backtrace()调用函数的位置,然后将正在运行的脚本的副本标记为提取参数表达式(如果调用行是foo(“hello $ user”)。$ indirect ($ user,5))?),

然而无论你有什么理由试图实现这一点 - 这是错误的原因。

下进行。

答案 5 :(得分:1)

好吧,时间到了一些丑陋的黑客,但这是我到目前为止所做的,我会尝试稍后再努力

<?php
class foo
{
    //Public so we can test it later
    public $bar;
    function foo()
    {
        //Init the array
        $this->bar = array();
    }
    function assign($__baz)
    {
        //Try to figure out the context
        $context = debug_backtrace();
        //assign the local array with the name and the value
        //Alternately you can initialize the variable localy
        //using $$__baz = $context[1]['object']->$__baz;
        $this->bar[$__baz] = $context[1]['object']->$__baz;
    }
}
//We need to have a calling context of a class in order for this to work
class a
{
    function a()
    {

    }
    function foobar()
    {
        $s = "testing";
        $w = new foo();
        //Reassign local variables to the class
        foreach(get_defined_vars() as $name => $val)
        {
            $this->$name = $val;
        }
        //Assign the variable
        $w->assign('s');
        //test it
        echo $w->bar['s'];
    }
}
//Testrun
$a = new a();
$a->foobar();

答案 6 :(得分:0)

不可能 - 最大您可以获得的信息量是您在转储时看到的信息

debug_backtrace();

答案 7 :(得分:0)

也许您想要做的是反过来,像这样的hackish解决方案工作正常:

<?php
  function assign($val)
  {
    global $$val;
    echo $$val;
  }
  $hello = "Some value";
  assign('hello');

输出:Some value

答案 8 :(得分:0)

你想做什么,PHP并不打算这样做。没有传统的方法来实现这一目标。事实上,只有非常奢侈的解决方案可用。一个与我能想到的一样接近PHP的是创建一个新类。

您可以将其称为NamedVariable或其他内容,并且作为其构造函数,它将获取变量名称和值。您将其$products = new NamedVariable('products', $productData);启动,然后将其用作$this->view->assign($products);。当然,你的声明行现在很长,你的代码库中还有另一个 - 而且相当模糊 - 类,现在assign方法必须知道NamedVariable来提取变量名和值

正如大多数其他成员所回答的那样,你最好不要因为这种轻微缺乏的语法糖而受苦。请注意,另一种方法是创建一个识别assign()实例并重写源代码的脚本。现在,在运行代码之前,这将涉及一些额外的步骤,对于PHP而言,这是愚蠢的。您甚至可以将IDE配置为自动填充assign()。无论你选择什么,PHP本身都没有解决方案。

答案 9 :(得分:0)

此解决方案使用GLOBALS变量。要解决范围问题,变量通过引用传递,并将值修改为唯一。

function get_var_name(&$var, $scope=FALSE) {
    if($scope) $vals = $scope;
    else      $vals = $GLOBALS;
    $old = $var;
    $var = $new = 'unique'.rand().'value';
    $vname = FALSE;
    foreach ($vals as $key => $val) {
        if($val === $new) $vname = $key;
    }
    $var = $old;
    return $vname;
}

$testvar = "name";
echo get_var_name($testvar);  // "testvar"

function testfunction() {
    $var_in_function = "variable value";
    return get_var_name($var_in_function, get_defined_vars());
}

echo testfunction();  // "var_in_function"

class testclass {
    public $testproperty;
    public function __constructor() {
        $this->testproperty = "property value";
    }
}

$testobj = new testclass();
echo get_var_name($testobj->testproperty, $testobj);  // "testproperty"