我正在尝试编写一个bash脚本,在这样的php函数中添加一行:
public function register()
{
$this->app->bind('App\Repositories\Corporate\CorporateContract',
'App\Repositories\Corporate\EloquentCorporateRepository');
}
这是我的代码:
function bindContractToRepository {
sed -i -e '/register()\n/a \ \n\t\t'${repoBinding}' \n\t\t\t\t ' ./app/Providers/${repoName}${provider}.php 2> /dev/null
}
bindContractToRepository
我实际上希望我的代码能够进入函数本身,就像顶部的示例一样。
NB。我无法指定特定行,因为行号因版本不同而不同
答案 0 :(得分:0)
通常没有解析器就很难检测PHP函数边界。
我们可以在Bash中完成解析器的工作:逐行迭代代码,解决打开和关闭括号等问题,直到我们得到此函数覆盖的行数范围,最后用新的替换它内容。我们可以使用sed
commands执行相同的操作(在这种情况下,可能看起来不像汇编代码那么可读)。
但是我们已经有了一个PHP解析器!为什么不使用它?
以下PHP CLI脚本接受:
<强>更换-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\n");
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\n");
usage(true);
}
$new_code = $opt['c'] ?? $opt['code'] ?? null;
if (!$new_code) {
fprintf(STDERR, "Code option expected\n");
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\n");
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);
假设我们path/to/file.php
有A
类及其register
方法:
<?php
class A
{
public function register()
{
echo 'aaaa';
}
}
我们可以在Bash中替换A::register
方法的代码,如下所示:
php replace-method.php -i path/to/file.php -m 'A::register' -c - <<ENDOFPHP
public function register()
{
echo 'something new';
}
ENDOFPHP
我已在此处使用Bash文档进行输入。您可以使用任何类型的shell重定向,例如:
generate_php_code | php 1.php -i file.php -m 'A::register' -c -