dtfo55908 2016-10-08 11:07
浏览 61
已采纳

将php函数转换为bash字符串

I'm trying to write a bash script that adds a line into a php function like this:

public function register()
{
    $this->app->bind('App\Repositories\Corporate\CorporateContract',
        'App\Repositories\Corporate\EloquentCorporateRepository');
}

Here's my code:

function bindContractToRepository {
   sed -i -e '/register()
/a \ 
\t\t'${repoBinding}' 
\t\t\t\t ' ./app/Providers/${repoName}${provider}.php 2> /dev/null
}
bindContractToRepository

I actually want my code to come inside the function itself like the example at the top.

NB. I can't specify a particular line because the line number varies with different version

  • 写回答

1条回答 默认 最新

  • dtn43447 2016-10-08 12:34
    关注

    In general it is very difficult to detect PHP function boundaries without a parser.

    We can do the parser's job in Bash: iterate the code line by line, solve the opening and closing braces etc. until we get the range of lines covered by this function and, finally, replace it with new content. We can do the same using the sed commands (in this case will likely look less readable than an assembly code).

    But we already have a PHP parser! Why not use it?

    Example

    The following PHP CLI script accepts:

    • PHP input file (where we are going to replace a method/function);
    • PHP Method/function name
    • PHP code string for the replacement as a string, or dash(the standard input)

    replace-method.php

    <?php
    function usage($error = false) {
      global $argv;
    
      $str = <<<EOS
    USAGE: php {$argv[0]} OPTIONS
    
    OPTIONS:
    
    -h, --help         Print help message
    -i, --input-file   Input PHP file
    -m, --method       PHP function/method name, e.g.:
                       my_func, MyClass::myMethod
    -c, --code         The new PHP code including the function/method declaration.
                       String of code, or dash ('-') meaning the standard input.
    
    EXAMPLE:
    
    php {$argv[0]} -i source/file.php -m 'MyClass::register' -c - <<ENDOFPHP
      public function register()
      {
        echo time();
      }
    
    ENDOFPHP
    
    Replaces the code of 'MyClass::register' method with new code from the standard input
    in source/file.php.
    
    EOS;
      fprintf($error ? STDERR : STDOUT, $str);
      exit((int)!$error);
    }
    
    if (false === ($opt = getopt('hi:m:c:', ['help', 'input-file:', 'method:', 'code:']))) {
      fprintf(STDERR, "Failed to parse options
    ");
      usage(true);
    }
    
    
    if (isset($opt['h']) || isset($opt['help']))
      usage();
    
    // Using PHP7 Null coalescing operator
    $file = $opt['i'] ?? $opt['input-file'] ?? null;
    if (!file_exists($file)) {
      fprintf(STDERR, "File '$file' does not exist
    ");
      usage(true);
    }
    
    $new_code = $opt['c'] ?? $opt['code'] ?? null;
    if (!$new_code) {
      fprintf(STDERR, "Code option expected
    ");
      usage(true);
    }
    if ($new_code == '-')
      $new_code = file_get_contents('php://stdin');
    
    $method = $opt['m'] ?? $opt['method'] ?? null;
    if (!$method) {
      fprintf(STDERR, "Method option expected
    ");
      usage(true);
    }
    
    // You most likely want to include project's autoloading file instead.
    // (You might accept it as a CLI argument, too.)
    require_once $file;
    
    $rf = strpos($method, '::') ?
      new ReflectionMethod($method) :
      new ReflectionFunction($method);
    $start_line = $rf->getStartLine();
    $end_line = $rf->getEndLine();
    
    $lines = file($file);
    
    $code = implode(array_slice($lines, 0, $start_line - 1)) .
      $new_code . implode(array_slice($lines, $end_line));
    
    file_put_contents($file, $code);
    

    Suppose we have path/to/file.php with A class and its register method:

    <?php
    class A
    {
      public function register()
      {
        echo 'aaaa';
      }
    }
    

    We can replace the code of A::register method in a Bash as follows:

    php replace-method.php -i path/to/file.php -m 'A::register' -c - <<ENDOFPHP
      public function register()
      {
        echo 'something new';
      }
    ENDOFPHP
    

    I've used Bash here document for input. You can use any kind of the shell redirection, for instance:

    generate_php_code | php 1.php -i file.php -m 'A::register' -c -
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 矩阵加法的规则是两个矩阵中对应位置的数的绝对值进行加和
  • ¥15 活动选择题。最多可以参加几个项目?
  • ¥15 飞机曲面部件如机翼,壁板等具体的孔位模型
  • ¥15 vs2019中数据导出问题
  • ¥20 云服务Linux系统TCP-MSS值修改?
  • ¥20 关于#单片机#的问题:项目:使用模拟iic与ov2640通讯环境:F407问题:读取的ID号总是0xff,自己调了调发现在读从机数据时,SDA线上并未有信号变化(语言-c语言)
  • ¥20 怎么在stm32门禁成品上增加查询记录功能
  • ¥15 Source insight编写代码后使用CCS5.2版本import之后,代码跳到注释行里面
  • ¥50 NT4.0系统 STOP:0X0000007B
  • ¥15 想问一下stata17中这段代码哪里有问题呀