【问题标题】:Passing variable between functions - php在函数之间传递变量 - php
【发布时间】:2013-09-25 23:10:17
【问题描述】:

以下是我实际代码的编辑版本:

<?php

include ('login_info.php');

class modernCMS {

var $host;
var $username;
var $password;
var $db;
var $url;


function connect(){
    $con = mysql_connect($this->host, $this->username, $this->password);
    mysql_select_db($this->db, $con) or die(mysql_error());

mysql_set_charset('utf8');

}


function get_coordinates(){

$sql ="select lat, lng from postcodes LIMIT 1;";
    $res = mysql_query($sql) or die(mysql_error());
    while($row = mysql_fetch_assoc($res)){
        $lat = $row['lat'];
        $lng = $row['lng'];

    }
}


 function get_name(){

 $sql ="select name from places WHERE lat=$lat AND lng=$lng LIMIT 1;";
    $res = mysql_query($sql) or die(mysql_error());
    while($row = mysql_fetch_assoc($res)){
        $name = $row['name'];

echo $name;


     }
}


?>

然后在一个单独的文档中,我有一个包含上述文件的文件。我使用以下方法调用函数获取名称:

<?=$obj->get_name()?>

get_name 实际上包含用于计算两点之间距离的计算,但是因为它是一个冗长的计算,我已将其排除在上面的示例之外。

重要的是我可以使用 $obj->get_name() 来获取 $lat 和 $lng 的输出

【问题讨论】:

  • 您可以将它们作为参数传递
  • 如果你需要一个 getter 和 setter,创建一个 Coordinate 对象。 PHP 是一种 OOP 语言 :-)
  • 你需要了解variable scope。但是,使用参数、返回值、数组、对象和属性之类的东西都比使用全局变量更好

标签: php function variables


【解决方案1】:

您遇到了范围界定问题。这些变量仅对声明它们的函数可用。为了使它们可用,您可以将变量显式传递给函数(您需要确保始终在 display_coordinates() 之前调用 get_coordinates(),否则您将有未定义的值),或者使用全局变量(坏主意) .

最好的方法可能是为它创建一个类(尽管这取决于你打算如何使用它)。您的变量将始终在范围内,您不会冒在初始化变量之前尝试运行 display_coordinates() 函数的风险。

class Coordinate
{
    // These are the variables where the coords will be stored.
    // They are available to everything within the {}'s after 
    // "class Coordinate"  and can be accessed with
    // $this->_<varname>.
    protected $_lat;
    protected $_long;

    // This is a special function automatically called when 
    // you call "new Coordinate"
    public function __construct($lat, $long)
    {
        // Here, whatever was passed into "new Coordinate" is
        // now stored in our variables above.
        $this->_lat  = $lat;
        $this->_long = $long;
    }

    // This takes the values are stored in our variables,
    // and simply displays them.
    public function display()
    {
        echo $this->_lat;
        echo $this->_long;
    }
}

// This creates a new Coordinate "object". 25 and 5 have been stored inside.
$coordinate = new Coordinate(25, 5); // 25 and 5 are now stored in $coordinate.
$coordinate->display(); // Since $coordinate already "knows" about 25 and 5
                        // it can display them.

// It's important to note, that each time you run "new Coordinate",
// you're creating an new "object" that isn't linked to the other objects.
$coord2 = new Coordinate(99, 1);
$coord2->display(); // This will print 99 and 1, not 25 and 5.

// $coordinate is still around though, and still knows about 25 and 5.
$coordinate->display(); // Will still print 25 and 5.

您应该阅读Variable ScopeClasses and Objects 以了解更多信息。

要将其与您的原始代码放在一起,您可以这样做,

function get_coordinates()
{
     return new Coordinate(25, 5);
}

function display_coordinates($coord)
{
    $coord->display();
}

$c = get_coordinates();
display_coordinates($c);
// or just "display_coordinates(get_coordinates());"


问题更新后编辑

您的代码中有一些不好的做法,但这里有一些快速的步骤来获得您想要的。

// Copy the Coordinate class from my answer above, but add two new
// lines before the final "}"
public function getLatitude()  { return $this->_lat; }
public function getLongitude() { return $this->_long; }

// Put the Coordinate class definition before this line
class modernCMS {

/////

// In your code, after this line near the top
var $url;

// Add this
var $coord;

/////

// In your get_coordinates(), change this...
$lat = $row['lat'];
$lng = $row['lng'];

// To this...
$this->coord = new Coordinate($lat, $lng);

/////

// In your get_name(), add two lines to the start of your function.
function get_name(){
    $lat = $this->coord->getLatitude();
    $lng = $this->coord->getLongitude();

与您的问题无关,但您还应该阅读“SQL 注入”,因为 get_name() 中的查询易受攻击。这里没什么大不了的,因为无论如何数据都来自您的其他查询,但仍然是不要直接在查询字符串中使用参数的好习惯。

【讨论】:

  • 这个例子让我很困惑,因为你似乎是在两个函数之外设置值。重要的是,在第一个函数中设置值是否来自 sql 语句。
  • 我会在代码中添加一些cmets来尝试使其更清晰易懂。
  • 我添加了 cmets 以希望更好地解释正在发生的事情。不过,在如此简短的答案中只能解释这么多。阅读我最后引用的两份文档将是全面了解正在发生的事情的最佳方式。不要被文档的长度吓到,这不是一开始就容易掌握的东西,但范围界定和类/对象都是一个重要的学习主题。
  • 最后一个问题:我可以设置:$coordinate = new Coordinate(25, 5);在单独的函数中?
  • @andrewanderson 您可以在另一个函数中加载坐标,调用new Coordinate(...)返回新的坐标对象。然后可以将其传递给任何其他函数。不需要全局变量。 (Rich,也许您可​​以更新您的答案以展示您如何做到这一点 - 这已经是一个很好的答案,或者我会将它添加到我的答案中)。
【解决方案2】:

函数在函数范围内运行,因此您在get_coordinates() 中设置的变量是局部变量。要创建全局变量,可以使用 global 关键字:

<?php

function get_coordinates()
{
global $lat, $lng;
$lat = 25;
$lng = 5;
}

function display_coordinates()
{
global $lat, $lng;
echo $lat;
echo $lng;
}

get_coordinates();
display_coordinates();

$GLOBALS数组:

<?php

function get_coordinates()
{
$GLOBALS['lat'] = 25;
$GLOBALS['lng'] = 5;
}

function display_coordinates()
{
echo $GLOBALS['lat'];
echo $GLOBALS['lng'];
}

get_coordinates();
display_coordinates();

但是,这可能不是设置/访问这些变量的最佳方式,因为任何函数都可以随时更改它们的状态,并且您必须先调用一个函数来设置它们,然后再调用另一个函数来显示它们。如果你能描述你的具体目标,你可能会得到更好的建议。

一个更好的方法是使用一个类,然后将对象传递到你需要的地方(这个简单的例子没有证明正确的encapsulation,但它是一个很好的起点):

<?php

class Coordinates {
  public $lat;
  public $lng;

  public function __construct($lat, $lng) {
    $this->lat = $lat;
    $this->lng = $lng;
  } 

  public function display_coordinates() {
    echo $this->lat . "\n";
    echo $this->lng . "\n";
  }
}

function get_coordinates() {
  return new Coordinates(25, 5);
}

$coords = get_coordinates();
$coords->display_coordinates();


function output_coordinates($coordinates) {
  $coordinates->display_coordinates();
}
output_coordinates($coords);

PHP 中常用的另一种方法是在关联数组(索引字符串的数组)中传递内容。我通常不喜欢这样,因为数组没有声明它打算保存的内容,但它是一个选项:

<?php

function get_coordinates() {
  return array('lat' => 25, 'lng' => 5);
}

function output_coordinates($coordinates) {
  echo $coordinates['lat'] . '\n';
  echo $coordinates['lng'] . '\n';
}

$coords = get_coordinates();
output_coordinates($coords);

【讨论】:

  • 类和对象自动更好 ?
  • @Dagon 没有?我也不是有意暗示的。但它有助于依赖、封装和责任,因为您将相似的属性和方法组合在一起,消除了记住全局空间中的内容(以及在什么时候)的负担。这段代码并不长也不复杂,但更有条理,更容易扩展。
  • 它的大胆大胆吸引了我,但没有打算打发髻;-)
  • 上面使用 global 或 $GLOBALS 的两个示例都对我不起作用。我不确定我是否在这里遗漏了一些非常简单的东西。
  • @Dagon 我只是想真正提供帮助并指出一种更好的做事方式。
【解决方案3】:

会话呢? https://www.php.net/manual/en/reserved.variables.session.php

创建新会话

session_start();
/*session is started if you don't write this line can't use $_Session  global variable*/
$_SESSION["newsession"]=$value;

获取会话

session_start();
/*session is started if you don't write this line can't use $_Session  global variable*/

$_SESSION["newsession"]=$value;
/*session created*/

echo $_SESSION["newsession"];
/*session was getting*/

更新会话

session_start();
/*session is started if you don't write this line can't use $_Session  global variable*/

$_SESSION["newsession"]=$value;
/*it is my new session*/

$_SESSION["newsession"]=$updatedvalue;
/*session updated*/

删除会话

session_start();
/*session is started if you don't write this line can't use $_Session  global variable*/

$_SESSION["newsession"]=$value;

unset($_SESSION["newsession"]);
/*session deleted. if you try using this you've got an error*/

【讨论】:

    【解决方案4】:

    一种方法:

    function get_coordinates(&$lat, &$lng)
    {
         $lat = 25;
         $lng = 5;
    }
    
    function display_coordinates($lat, $lng)
    {
         echo $lat;
         echo $lng;
    }
    
    $lat = 0;
    $lng = 0;
    
    // assign values to variables
    get_coordinates( $lat, $lng );
    
    // use function to display them...
    display_coordinates ($lat, $lng);
    

    【讨论】:

      【解决方案5】:

      创建一个Coordinate.class.php 文件:

      <?php
      class Coordinate {
        var $latitude;
        var $longitude;
      
        public function getLatitude() {
          return $this->latitude;
        }
      
        protected function setLatitude($latitude) {
          $this->latitude = floatval($latitude);
        }
      
        public function getLongitude() {
          return $this->longitude;
        }
      
        protected function setLongitude($longitude) {
          $this->longitude = floatval($longitude);
        }
      
        public function __construct() {
          // Overload
          if (func_num_args() == 2) {
            $this->setLatitude(func_get_arg(0));
            $this->setLongitude(func_get_arg(1));
          }
          // Default
          else {
            $this->setLatitude(0);
            $this->setLongitude(0);
          }
        }
      
        public function displayCoordinate() {
          printf("Latitude: %.2f, Longitude: %.2f\n",
            $this->getLatitude(),
            $this->getLongitude());
        }
      }
      
      function main() {
        $c = new Coordinate (25, 5);
        $c->displayCoordinate();
      }
      
      main();
      ?>
      

      【讨论】:

        【解决方案6】:

        换一个帖子..我认为更好的方法:

        function get_coordinates()
        {
            return array(
                "lat" => 25,
                "lng" => 5
            );
        
        }
        
        function display_coordinates($latLongArray)
        {
             echo $latLongArray['lat'];
             echo $latLongArray['lng'];
        }
        
        
        // assign values to variables
        $latLongArray = get_coordinates();
        
        // use function to display them...
        display_coordinates ($latLongArray);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-07-02
          • 2013-04-09
          • 2013-03-07
          • 2017-03-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多