我正在尝试编写一个 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
我实际上希望我的代码像顶部的示例一样进入函数本身。
注意。我无法指定特定的行,因为行号因版本而异
最佳答案
一般在没有解析器的情况下很难检测 PHP 函数边界。
我们可以在 Bash 中完成解析器的工作:逐行迭代代码,解决左大括号和右大括号等问题,直到我们获得此函数涵盖的行范围,最后用新内容替换它。我们可以使用 sed
commands 来做同样的事情(在这种情况下,可能看起来不如汇编代码可读)。
但是我们已经有了一个 PHP 解析器!为什么不用它?
例子
以下 PHP CLI 脚本接受:
- PHP 输入文件(我们将在其中替换方法/函数);
- PHP 方法/函数名称
- 用于替换为字符串或破折号(标准输入)的 PHP 代码字符串
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\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 here 文档进行输入。您可以使用任何类型的 shell 重定向,例如:
generate_php_code | php 1.php -i file.php -m 'A::register' -c -
关于php - 将 php 函数转换为 bash 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39931635/