Передача переменной ее родительской функции в PHP?

У меня есть функция с функцией, и мне нужна внутренняя функция, чтобы сделать ее переменные доступными в области родительской функции, например:

function sayMyName(){
    getName(); // inner function generates $name value

    echo $name; // use $name
}

sayMyName();

Я мог бы легко просто глобализировать вещи с помощью обеих функций... Но моя ситуация намного сложнее и обрабатывает больше переменных, и глобализация каждой из них немного утомительна.

Спасибо.

PS я заметил много предложений "возврата". извините, я не понял, мне нужно вернуть больше переменных .. не простой возврат. Спасибо ребята


person BrownChiLD    schedule 17.04.2013    source источник
comment
Если вам нужно получить доступ к переменной таким образом, скорее всего, ваш дизайн несовершенен. Если такая потребность действительно существует, подумайте о возврате этой переменной из функции или (худшее решение) с использованием параметров по ссылке.   -  person Aleks G    schedule 17.04.2013
comment
Почему вы не работаете с объектно-ориентированными классами и т.п.?   -  person silkfire    schedule 17.04.2013
comment
Черт возьми, неужели так трудно понять, что этот человек, скорее всего, все еще изучает, как работает PHP? Перестаньте забрасывать его дизайном и объектно-ориентированными вещами — вы никого не впечатлите и никому не поможете.   -  person Lee White    schedule 17.04.2013
comment
ха-ха, я знаю, что получу здесь ООП-комментарии.. спасибо за защиту, Арно, но, честно говоря, я кодирую php уже более 10 лет.. и да, я тоже занимаюсь ООП.. к сожалению, у меня не было формального обучения , все, что я только что подобрал по пути. читать учебники и т. д. я стал довольно хорошо, но время от времени у меня есть вопросы. я пообещал себе больше не отвечать на вопрос ПОЧЕМУ НЕ ООП... в отличие от других, использующих другие библиотеки и фреймворки, я фактически создал свои собственные библиотеки функций и классов, МОЙ ПУТЬ...   -  person BrownChiLD    schedule 17.04.2013
comment
в любом случае все, что мне действительно нужно было знать, это возможно ли это каким-то образом, с помощью техники или обходного пути или даже в новых версиях PHP (которые не были обновлены до последней версии) ... вот и все. если нет, то у меня есть куча других способов добиться того, чего я хочу... и да, я использую ООП, но когда мне нужно... например, для моих требований CRUD... но лично я не верю/согласен с ООП на 100% концепция, специально для множества простых вещей, которые я не нахожу ... это тот же аргумент, что и ЗАЧЕМ ПОМЕЩАТЬ CSS STYLING непосредственно в ваш элемент DIV, когда вы можете отделить его в блоке / файле CSS.   -  person BrownChiLD    schedule 17.04.2013


Ответы (9)


Вы можете использовать $_GLOBALS, но это "плохая практика". Так,


1. Используйте return:

<?php
function getName(){
    $name = 'Smith';

    return $name;
}

function sayMyName(){
    $name = getName();

    echo $name;
}

sayMyName();
?>

Показывает:

Smith

2. Используйте references:

<?php
function getName(&$name){
    $name = 'Smith';
}

function sayMyName(){
    getName($name);

    echo $name;
}

sayMyName();
?>

Показывает:

Smith

3. Возврат array для нескольких переменных :

<?php
function getName(){
    $surname = 'Smith';
    $name    = 'John';

    return array($surname, $name);
}

function sayMyName(){
    list($surname, $name) = getName();

    echo $name, ' ', $surname;
}

sayMyName();
?>

Показывает:

John Smith

4. Возврат пользовательского object для нескольких переменных:

<?php
function getName(){
    $surname = 'Smith';
    $name    = 'John';

    $buffer = new stdClass();

    $buffer->name    = $name;
    $buffer->surname = $surname;

    return $buffer;
}

function sayMyName(){
    $obj = getName();

    echo $obj->name, ' ', $obj->surname;
}

sayMyName();
?>

Показывает:

John Smith

5. Используйте anonymous function с оператором use и references:

<?php
function sayMyName(){
    $surname = $name = 'Unknown';

    $temp = function() use (&$name, &$surname){
        $surname = 'Smith';
        $name    = 'John';
    };

    $temp();

    echo $name, ' ', $surname;
}

sayMyName();
?>

Показывает:

John Smith
person BlitZ    schedule 17.04.2013
comment
Вау, спасибо, чувак.. куча идей.. я думаю, что я возьму маршрут возвращаемого массива и просто проанализирую его в родительской функции - person BrownChiLD; 17.04.2013
comment
@BrownChiLD, наверное, я никогда не думал об этом. :) Спасибо вам. И да, я разделяю концепцию, которую вы написали выше. - person BlitZ; 17.04.2013

сделай это

function sayMyName(){
    $name = getName(); // inner function generates $name value

    echo $name; // results will be returned
}

sayMyName();

Я надеюсь, что ваша внутренняя функция возвращает имя, подобное этому

function getName(){
    return $name;
}

тогда это сработает

person chandresh_cool    schedule 17.04.2013
comment
спасибо, чувак, это работает, но мне нужно было отправить несколько vars обратно в родительскую функцию, а не только 1.. если return $name,$age,$etc не может работать, лолз. - person BrownChiLD; 17.04.2013
comment
В этом случае создайте массив и поместите пары ключ-значение. Верните массив, а затем получите доступ к этим значениям, используя возвращенный массив. - person chandresh_cool; 17.04.2013

Именно для этого было разработано объектно-ориентированное программирование. Если многие функции должны совместно использовать переменные, вероятно, лучше всего инкапсулировать их в класс следующим образом:

class WhateverDescibestYourViewOfTheWorld {
    protected $name;

    function __construct( $name)
    {
        $this->name = $name;
    }

    function GetName() {
        return $this->name;
    }

    function SayName()
    {
        echo $this->name;
    }
}

// And use it:
$o = new WhateverDescibestYourViewOfTheWorld();
...
$o->SayName();

Или вы можете создать класс, который будет использоваться только как контейнер данных:

class DataContainer {
    public $name;
    public $address;
    // ...
}

// By reference this will modify object previously created
function GetProperties( &$dataContainer) // Note that & isn't necessary since PHP5
{
    $dataContainer->name = "...";
}

$c = new DataContainer();
GetProperties($c);

Или вы можете упростить это и использовать массив:

function GetProperties( array &$dataContainer)
{
     $dataContainer['name'] = '...';
}

$data = array();
GetProperties($data);
person Vyktor    schedule 17.04.2013
comment
Проверьте третий комментарий к вопросу. - person Lee White; 17.04.2013
comment
@ArnoSluismans да, вы правы ... Я был слишком оскорбителен, я добавил больше полезных заметок и примеров о том, как это сделать (все же ООП - лучшее решение, за исключением очень редких случаев). - person Vyktor; 17.04.2013
comment
tbh ООП в php очень редко является лучшим решением, но каждый сам по себе;) - person Dave; 17.04.2013

Как насчет того, чтобы сначала присвоить возвращаемое значение getName() переменной?

$name = getName();
person bwoebi    schedule 17.04.2013

Если вам нужна только одна переменная, вы можете сделать это

function getName(){
    // Some code
    return 'my name is XXX';
}
function sayMyName(){
     $name = getName(); // inner function generates $name value
     echo $name; // results to undefined
 }
 sayMyName();

В противном случае вы можете рассмотреть возможность использования класса: http://www.php.net/manual/en/language.oop5.php

person syl.fabre    schedule 17.04.2013

Вы можете использовать ссылки

    $param = "aaa";
    function f(&$param)
    {
      //dostuff
      inner($param);
      echo $param;
    }
    function inner(&$inner) { //do other stuff }

или используйте возвращаемое значение

 function f() { echo inner(); } 

 function inner($param) {return $param;}

если вы работаете со ссылками, обе функции будут работать с одной и той же переменной, а не с копией

http://php.net/manual/en/language.references.php

лучший способ был бы с классом

<?php 
class Person
{
 private $name;

 public function setName($name){ $this->name = $name;}
 public function sayName() {echo $this->name;}
}

$person = new Person();
$person->setName("Robert");
$person->sayName();

Это хороший способ сделать это в ООП.

person Robert    schedule 17.04.2013

То, что вы думаете, неверно, однако вы можете вернуть массив значений. Например:

function sayMyName()
{
    $result = getName(); // inner function creates an array

    echo $result['name']; 
}

или лучше объект:

class Results
{
    public $name;
}

function sayMyName()
{
    $result = getName(); // inner function creating an object

    echo $result->name;
}
person Sarrus    schedule 17.04.2013

Вы также можете сделать это, как показано ниже.

$name = "";

function sayMyName(){
    getName(); // inner function generates $name value
    //set $name variable inside getName() function.
    echo $name; // results to undefined
}

sayMyName();
person Dipesh Parmar    schedule 17.04.2013

Пожалуйста, используйте приведенный ниже код, это решит вашу проблему

global $var;

Вы можете использовать его в любом месте вашего диапазона php.

person Atanu    schedule 17.04.2013
comment
... и это также приведет к ненужному увеличению количества переменных глобальной области видимости, поэтому это обычно не рекомендуется. stackoverflow.com/q/12445972/2943403 - person mickmackusa; 06.05.2020