dre26973 2018-03-01 12:47
浏览 57
已采纳

如何在没有这些不良影响的情况下多次调用我的PHP函数?

I am experiencing a problem where the way I am calling a PHP function is causing incorrect output from a a class that otherwise acts properly.

Specifically, I am using the full-name-parser package to split full names in to "first", "middle" and "last" parts. It performs this task accurately.

However, I am trying to do it inside WordPress - specifically during an import via the WPAllImport plugin in which I am importing CSV data as WordPress Users.

WPAllImport supports execution of PHP functions (standard or custom) on import input data, allowing it to be manipulated before saving, eg. [function_name({input_field[1]})].

So I have crafted a wrapper function, get_name_part to allow me to split my input field name_full in to first, middle and last names for import to those corresponding WordPress fields. My get_name_part looks like this...

require_once '/home/mysite/public_html/wp-content/plugins/cxt-user-wpai-import/full-name-parser/vendor/autoload.php';

use ADCI\FullNameParser\Parser;

// name eg. Jokubas Phillip Gardner
// part eg. title, first, middle, last, nick, suffix,
// called via eg. [get_name_part({name_full[1]}, "first")]

function get_name_part($name, $part) {

    $parser = new Parser(
        [
            'part' => $part,
            // 'fix_case' => FALSE,
            'throws' => FALSE
        ]
    );

    // Return the parsed name part
    $nameObject = $parser->parse($name);

    // Give it back to WPAllImport
    return $nameObject;

}

That is, it should take the source name name_full and also a string corresponding to full-name-parser options which describe the name part (either first, middle or last).

In WPAllImport, then, I am calling these three lines, separately, in the WPAllImport fields for first_name, last_name and my custom name_mid...

[get_name_part({name_full[1]}, "first")]
[get_name_part({name_full[1]}, "middle")]
[get_name_part({name_full[1]}, "last")]

In theory, this should allow me to use a single wrapper function to spit back the specified part from the specified full name.

The problem is...

  1. The first operation completes successfully. That is, putting [get_name_part({name_full[1]}, "first")] in my import settings' first_name field successfully saves a parsed first name (eg. "Jokubas") in the first_name WordPress field.

  2. However, things break down after that. [get_name_part({name_full[1]}, "last")] places no name at all in the last_name field. It repeatedly fails.

  3. And [get_name_part({name_full[1]}, "middle")] places an incorrect combination of the actual middle and last (eg. "Phillip Gardner") as middle name.

So the actual output is:

  • First: Jokubas
  • Middle: Phillip Gardner
  • Last: [blank]

This is not consistent with full-name-parser itself, which correctly parses outside of my function and the import environment, like...

  • First: Jokubas
  • Middle: Phillip
  • Last: Gardner

I'm not sure what the reason is, but I feel like it may be something to do with calling the same function three times from the same import step, albeit with different parameters.

I appreciate that I have mentioned a couple of product names above which are not plain PHP. But I feel like there may something I could do in the function code to accommodate the fact that this function is getting called three times, with different parameters, in a single process; that the underlying reason may have something to do with this repetition or contamination.

I have, therefore, considered whether there is a need to destroy all variables at the end of the function. However, executing unset on $name, $part, $parser or $nameObject after the return does not fix anything.

What am I missing?

Thanks.

Edit:

WordPress debug.log shows:

[01-Mar-2018 15:43:06 UTC] WordPress database error Table 'context_wpdb.wpcxt_2_usermeta' doesn't exist for query SHOW COLUMNS FROM wpcxt_2_usermeta made by do_action('admin_init'), WP_Hook->do_action, WP_Hook->apply_filters, call_user_func_array, PMXI_Plugin->adminInit, PMXI_Admin_Manage->edit, PMXI_Admin_Import->template, PMXI_Model->setTable
[01-Mar-2018 15:43:06 UTC] WordPress database error Table 'context_wpdb.wpcxt_2_usermeta' doesn't exist for query SELECT umeta_id, meta_key FROM wpcxt_2_usermeta GROUP BY meta_key ORDER BY umeta_id made by do_action('admin_init'), WP_Hook->do_action, WP_Hook->apply_filters, call_user_func_array, PMXI_Plugin->adminInit, PMXI_Admin_Manage->edit, PMXI_Admin_Import->template, PMXI_Model_List->getBy

The PMXI* prefixes pertain to WPAllImport.

Edit 2:

Here are some valid ways in which full-name-parser operates on its own (ie. slices a supplied full name in to identified components)...

1.

Passing "part" as "all" (or not, since "all" is default) makes $nameObject an object containing all identified portions of the name...

require_once '/home/context/public_html/wp-content/plugins/cxt-user-wpai-import/full-name-parser/vendor/autoload.php';

use ADCI\FullNameParser\Parser;

$parser = new Parser(
    [
        'part' => 'all',
        // 'fix_case' => FALSE,
        'throws' => FALSE
    ]
);

$name = 'Jokubas Phillip Gardner';
$nameObject = $parser->parse($name);

print_r($nameObject);

... so the above outputs all available portions of the name...

FullNameParser\Name Object ( [leadingInitial:ADCI\FullNameParser\Name:private] => [firstName:ADCI\FullNameParser\Name:private] => Jokūbas [nicknames:ADCI\FullNameParser\Name:private] => [middleName:ADCI\FullNameParser\Name:private] => Phillip [lastName:ADCI\FullNameParser\Name:private] => Gardner [academicTitle:ADCI\FullNameParser\Name:private] => [suffix:ADCI\FullNameParser\Name:private] => [errors:ADCI\FullNameParser\Name:private] => Array ( ) )

That is correct behaviour.

2.

But passing only one portion of the name, eg. 'part' as 'last', like follows, makes $nameObject a string, containing only the one stated portion. So...

require_once '/home/context/public_html/wp-content/plugins/cxt-user-wpai-import/full-name-parser/vendor/autoload.php';

use ADCI\FullNameParser\Parser;

$parser = new Parser(
    [
        'part' => 'last',
        // 'fix_case' => FALSE,
        'throws' => FALSE
    ]
);

$name = 'Jokubas Phillip Gardner';
$nameObject = $parser->parse($name);

echo 'Here is my nameObject: ' . $nameObject . '<br />';

The above outputs the following only...

Gardner

That is also correct behaviour.

3.

Full-name-parser has named get* functions dedicated to obtaining individual portions, eg. getFirstName(), but they do not appear to be essential. I was attempting to use the part parameter instead.

  • 写回答

2条回答 默认 最新

  • dtu11716 2018-03-01 19:51
    关注

    Ok, the first attempt was wrong, but I think I found the problem.

    This behavior happens if there is a space at the end of the name. Actually the parser can not find the last name in this case, and throws an exception, but you have turned exceptions off.

    If you try

    $parser = new ADCI\FullNameParser\Parser(['throws' => FALSE]);
    
    var_dump($parser->parse('Jokubas Phillip Gardner '));
    

    You will see:

    class ADCI\FullNameParser\Name#2 (8) {
      private $leadingInitial =>
      NULL
      private $firstName =>
      string(7) "Jokubas"
      private $nicknames =>
      NULL
      private $middleName =>
      string(15) "Phillip Gardner"
      private $lastName =>
      NULL
      private $academicTitle =>
      NULL
      private $suffix =>
      NULL
      private $errors =>
      array(1) {
        [0] =>
        string(26) "Couldn't find a last name."
      }
    }
    

    So the solution is to trim your input.

    function get_name_part($name, $part) {
    
        $parser = new Parser(
            [
                'part' => $part,
                // 'fix_case' => FALSE,
                // 'throws' => FALSE
            ]
        );
    
        // Return the parsed name part
        return $parser->parse(trim($name));
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 unity第一人称射击小游戏,有demo,在原脚本的基础上进行修改以达到要求
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line