【问题标题】:PHP function is not returning dataPHP函数不返回数据
【发布时间】:2014-10-22 17:42:28
【问题描述】:

我有一个由函数创建的数据数组,但该函数不会返回数据。

函数如下:

/**
 * Takes in a legacy id and returns new id.
 */
function my_function($data) {
  foreach ($data as $info) {
    $new_info = my_other_function($info);
    $new_data[] = $new_info;
  }

  return $new_data;
}

这里是它的名字:

$data = array('7245');
echo 'test1';                   // prints out test1
$new_data = my_function($data);
print_r($new_data);                 // DOES NOT PRINT ANYTHING, SAME RESULTS WITH VAR_DUMP()
echo 'test2';                   // prints out test2

但是,如果我将函数更改为以下内容,它会在函数中打印出来,但仍然不会打印出返回值:

function my_function($data) {
  foreach ($data as $info) {
    $new_info = my_other_function($info);
    $new_data[] = $new_info;
  }
  print_r($new_data);
  return $new_data;
}

所以现在这样:

$data = array('7245');
echo 'test1';                   // prints out test1
$new_data = my_function($data);
echo 'test2';                   // prints out test2
print_r($new_data);                 // DOES NOT PRINT ANYTHING, SAME RESULTS WITH VAR_DUMP()

打印出来:

test1
array(0=>9876)
test2
// RETURNED VALUE SHOULD BE HERE BUT IT IS NOT

编辑:

因为这似乎根本不可能,所以我添加了原始函数,该函数位于 Drupal 模块中。我已经测试了这个函数中调用的所有其他函数,它们可以自己完美地工作。

$file_data = '7024';
$ids = tdm_migration_import_file($file_data, $inline='no');

function tdm_migration_import_file($data, $inline) {
  // create base array
  $new_data = array();
  if (!is_array($data)) {
    $data = array($data);
  }
  // if we are reprocessing this data, remove the first element (flag) of
  // the array
  // dpm($data, 'incoming data');
  if (isset($data['reprocess'])) {
    unset($data['reprocess']);
  }
  foreach ($data as $file_data) {
    if (trim($file_data) == '') {
      continue;
    }
    // check to see if this data is coming from a text block or not
    if ($inline == 'no') {
      // given a path or fid
      if (is_numeric($file_data)) {
        // given an int (fid)
        $legacy_fid = $file_data;
        $legacy_file_path = tdm_migration_get_legacy_file_data($legacy_fid);
        // set the flag to reprocess this data
        $new_data['reprocess'] = 'yes';
        // add file path to new data for reprocessing
        $new_data[] = $legacy_file_path;
      } else {
        // given a string (path or uri/url)
        $legacy_file_path = $file_data;
        $path_data = tdm_migration_extract_path_data($legacy_file_path);
        // // if the directory doesn't exist we create it and make sure permissions
        // allow for writing by the server
        file_prepare_directory($path_data['public_path'], FILE_CREATE_DIRECTORY);
        // check to see if the file already exists in file structure
        $realpath = drupal_realpath($path_data['public_file_path']);
        if (!file_exists($realpath)) {
          // create new file and get new fid
          $fid = tdm_migration_create_file($path_data['legacy_file_url'], $path_data['public_file_path'], $data='fid');
        } else {
          // get the existing file id
          $fid = tdm_migration_get_existing_file_data($path_data['public_file_path']);
        }
        $new_data[] = $fid;
      }
    } else {
      // given a body of text, find <img> tags and extract the src attributes
      $legacy_paths = tdm_migration_extract_img_srcs($file_data);
      $replacement_paths = array();
      foreach ($legacy_paths as $legacy_path) {
        $path_data = tdm_migration_extract_path_data($legacy_path);
        file_prepare_directory($path_data['public_path'], FILE_CREATE_DIRECTORY);
        $realpath = drupal_realpath($path_data['public_file_path']);
        if (!file_exists($realpath)) {
          $new_path = tdm_migration_create_file($path_data['legacy_file_url'], $path_data['public_file_path'], $data='path');
        } else {
          $new_path = $public_file_path;
        }
        // aggregate old and new paths
        $replacement_paths[$legacy_path] = $new_path;
      }
      // replace all old paths with new paths in original text
      $new_file_data = tdm_migration_replace_text($file_data, $replacement_paths);
      $new_data[] = $new_file_data;
    }
  }
  if (isset($new_data['reprocess']) && $new_data['reprocess'] == 'yes') {
    // dpm($new_data, 'reprocessing');
    tdm_migration_import_file($new_data, $inline='no');
  } else {
    dpm($new_data, 'new-data'); // THIS PRINTS OUT!!!!!!
    return $new_data;
  }
}

EDIT2:这似乎有些混乱,所以我将用简单的英语解释这些步骤。

  1. $data = '7204';数据变量被设置为一串数字
  2. 将 $data 放入一个数组中,也称为 $data。
  3. 检查$data中是否设置了key 'reprocess',如果是,删除它
  4. 遍历 $data 数组,数组的各个元素现在称为 $file_data(此函数根据迁移需要下载文件)。
  5. 如果元素为空,则跳过它并转到下一个元素
  6. 检查是否设置了 $inline 变量,如果是,我们正在处理 HTML(不是手头的问题) 在这种情况下,数据是一串数字。 $inline 永远不会设置为“是”。
  7. 检查元素是否为数字,在本例中为数字
  8. 使用 tdm_migration_get_legacy_file_data() 获取存储在旧数据库中的相对路径。新数据类似于:sites/default/files/somefile.jpg
  9. 在 new_data 中将 reprocess 设置为 yes
  10. 将返回的文件路径添加到new_data数组中。
  11. 现在该函数使用最后一个 if/else 进入底部,并检查是否重新处理 isset 以及是否等于 yes - 在这种情况下它是!
  12. 由于 reprocess 等于 yes,我们使用给定的字符串(路径)再次运行该函数!
  13. UNSET 重新处理!
  14. 再次遍历数据
  15. 非内联
  16. 不是数字! 所以现在永远不会设置重新处理!!!
  17. 获取路径数据(返回新的服务器路径等)- 验证工作
  18. 准备具有写入权限的目录,如果不存在则创建它
  19. 检查文件是否已经存在于服务器上
  20. 如果没有,则创建文件并通过运行 tdm_migration_create_file() 将文件信息添加到数据库中,这将返回文件 ID ($fid)。 - 验证工作 - 如果确实存在,它只会检查数据库中的文件 ID - 验证工作
  21. 将文件 ID 添加到 $new_data。
  22. 现在在函数的底部,它转到 ELSE,因为未设置 REPROCESS,应该返回数据

最后一部分是错误的。如果添加行 dpm($new_data, 'new-data');在返回之前,它会准确地打印出它应该打印的内容。对于初学者来说,dpm 是一个以干净格式打印数据的 drupal 功能。如果它将 dpm 行更改为 var_dump($new_data);死(); - 它仍然打印数据,但函数不会返回它!

【问题讨论】:

  • 简而言之:这是不可能的。请提供一个代码块,我们可以复制、粘贴并按原样运行来显示这个确切的问题。
  • 对我来说似乎工作正常:eval.in/184938
  • @deceze - 现在试图找到一种方法来做到这一点......这是在一个drupal模块中,并且正在连接到两个数据库以检索数据......我没有捷径可以解释它,所以我会处理它并更新问题。
  • 尝试var_dump() 而不是print_r()。如果它实际上没有放任何东西,它应该打印NULL
  • @Samsquanch - 我用来打印的实际函数是 dpm() ,它是一个 drupal 函数,但我想我会把 print_r 放在这里给那些不了解 Drupal 的人。与 var_dump() 的结果相同

标签: php return return-value


【解决方案1】:

你的函数在这里没有返回数据!

  ...
  if (isset($new_data['reprocess']) && $new_data['reprocess'] == 'yes') {
    // vvvvvvvvvvvvvvvvvvvvv
    tdm_migration_import_file($new_data, $inline='no');
    // ^^^^^^^^^^^^^^^^^^^^^
  } else {
    return $new_data;
  }

函数再次调用自身并不重要。它可以调用 any 函数,这无关紧要。这里没有return 语句,所以如果它进入if 分支,函数不会返回数据。修复它:

 return tdm_migration_import_file($new_data, $inline='no');

非常典型的新手递归调用错误。


显然我需要更清楚为什么这不像你想的那样工作。首先:递归没有什么特别之处!你只是在调用一个函数。与您当前使用的功能相同并不重要。在这种情况下不会发生特殊的魔法。

以这个函数为例:

function foo() {
    if (rand(0, 1)) {
        bar();
    } else {
        return true;
    }
}

这个函数只返回true 一半的时间。另一半,它将调用一个函数bar,该函数会执行who-knows-what,但不会从该调用返回任何值。

现在将bar() 替换为foo()。它不会改变我上面描述的行为。该函数仍将只返回一半的数据。如果没有return 语句,它不会返回数据。干净利落。甚至来自递归调用。

递归调用函数不会“重新启动”该函数,它会创建另一个函数调用,其规则与任何其他函数调用相同。如果 reprocess 等于 yes, period,则您的函数不会返回数据。

【讨论】:

  • 不错的收获。我没有意识到这是一个递归调用。
  • 如果是这样,那么我回到我的答案恢复到“神奇的 PHP”。
  • @CR47 我添加了更长的解释来反驳您的第 12 步和/或第 22 步。
  • @CR47 不,它不起作用。 bar(); 不返回数据。 return bar(); 返回数据。
  • @CR47 大声朗读代码的作用:如果 reprocess 为真,则调用 [a function],否则返回数据。 仅在以下两种情况之一中返回数据在这里。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-17
  • 1970-01-01
  • 2013-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多