在函数内部终止脚本是不好的做法吗?
is it bad practice to kill a script inside of a function?
我指的是将 die() 函数用于除调试之外的其他用途。
这是 "well it works" 的情况,但这是不好的做法吗?
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
/**
* This Command will help Cjw create a new demo site to start off
* with the Multisite bundle.
*
* Class CreateSiteCommand
* @package Cjw\GeneratorBundle\Command
*/
class RemoveSiteCommand extends ContainerAwareCommand
{
private $vendor; //eg "Cjw"
private $fullBundleName; //eg "SiteCjwNetworkBundle"
private $fullBundleNameWithVendor; //eg "CjwSiteCjwNetworkBundle"
(more vars)
/**
* this function is used to configure the Symfony2 console commands
*/
protected function configure()
{
$this
->setName('cjw:delete-site')
->setDescription('Delete Cjw Site')
->addOption('db_user', null, InputOption::VALUE_REQUIRED, 'If set, the database user will be shown on the instructions');
}
/**
* This function executes the code after the command input has been validated.
*
* @param InputInterface $input gets the user input
* @param OutputInterface $output shows a message on the command line
* @return int|null|void
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
// set optional db_username
$dialog = $this->getHelper('dialog');
$reusable = new \Reusable();
$fs = new Filesystem();
$cmd = new \ColorOutput();
//push only vendors into the vendors array
$vendors = $reusable->getFileList($reusable->getMainDirectory('src'),true);
//select a vendor from the array
$vendor = $dialog->select(
$output,
'Select your vendor [1]: ',
$vendors,
1
);
$bundles_in_vendor = $reusable->getFileList($reusable->getMainDirectory('src/'.$vendors[$vendor]),true);
//push bundles that start with 'Site' into array
$sites = array();
foreach($bundles_in_vendor as $bundle)
{
if($reusable->startsWith($bundle,'Site'))
{
array_push($sites,$bundle);
}
}
$site_to_delete = $dialog->select(
$output,
'Select site to remove: ',
$sites,
1
);
$bundle_deletion_path = $reusable->getMainDirectory('src/'.$vendors[$vendor]).'/'.$sites[$site_to_delete];
$are_you_sure = array('yes','no');
$confirmation = $dialog->select(
$output,
'Are you sure you want to delete: '.$sites[$site_to_delete],
$are_you_sure,
1
);
if($are_you_sure[$confirmation] == 'yes')
{
echo $cmd->color('yellow','attempting to remove bundle in: '.$bundle_deletion_path);
$fs->remove($bundle_deletion_path);
//returns demo
$sitename = strtolower($sites[$site_to_delete]);
$sitename = substr($sitename,0,-6);
$sitename = substr($sitename,4);
$this->setRawSiteNameInput($sitename);
// returns acmedemo
$symlinkname = strtolower($vendors[$vendor].substr($sites[$site_to_delete],0,-6));
$this->removeSymlinks($symlinkname,$this->getRawSiteNameInput());
$this->createSetters($vendor,substr($sites[$site_to_delete],0,-6));
$this->deleteEzPublishExtension();
echo $this->getFullLegacyPath();
echo $cmd->color('green','deletion process completed.');
}
else
{
echo "deletion canceled";
die();
}
function_that_further_deletion_process();
}
这是一个 symfony2 控制台脚本,可以从特定结构中删除站点
如果这是您的问题,那是绝对安全的,因为 php 作为一种准解释语言,在终止执行时不会留下任何痕迹或人工痕迹。
如果这是一个好的做法是另一回事。我会说它可以用于测试目的,但您应该在最终代码中避免使用它。原因是它使代码难以维护。考虑其他人深入研究您的代码并试图理解其中的逻辑。人们实际上必须通过 all 代码才能偶然发现这一细节。机会是一个没有,所以你的代码的行为似乎被破坏了。
改为尝试执行以下操作之一:
抛出异常离开当前作用域。这样的异常很可能会被调用范围捕获并吞没,但它是一种清晰且可预测的 returning 方式。显然你应该记录这样的行为。
return 一个值显然超出了 "normally" 被 return 编辑的范围。因此,例如 null
或 false
而不是典型值。这会强制调用作用域检查 return 值,但无论如何这都是很好的做法。
重组您的代码,这样就没有理由突然终止执行。
您还没有告诉我们您的意图是什么 die
.. 因此我们无法判断您是否使用了正确的工具...
die
和它的同义词 exit
都退出脚本。如果那是你想要的,那很好。
我倾向于将 exit
用于正常操作,将 die
用于错误情况(无法正确恢复的情况,例如:无法连接到数据库)。我还为 die
使用包装器,因此如果需要,我可以记录此类事件。虽然两个命令做同样的事情,但意图不同,我想在代码中表达这个意图。
在您的示例中,我将使用 exit
。
我指的是将 die() 函数用于除调试之外的其他用途。 这是 "well it works" 的情况,但这是不好的做法吗?
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
/**
* This Command will help Cjw create a new demo site to start off
* with the Multisite bundle.
*
* Class CreateSiteCommand
* @package Cjw\GeneratorBundle\Command
*/
class RemoveSiteCommand extends ContainerAwareCommand
{
private $vendor; //eg "Cjw"
private $fullBundleName; //eg "SiteCjwNetworkBundle"
private $fullBundleNameWithVendor; //eg "CjwSiteCjwNetworkBundle"
(more vars)
/**
* this function is used to configure the Symfony2 console commands
*/
protected function configure()
{
$this
->setName('cjw:delete-site')
->setDescription('Delete Cjw Site')
->addOption('db_user', null, InputOption::VALUE_REQUIRED, 'If set, the database user will be shown on the instructions');
}
/**
* This function executes the code after the command input has been validated.
*
* @param InputInterface $input gets the user input
* @param OutputInterface $output shows a message on the command line
* @return int|null|void
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
// set optional db_username
$dialog = $this->getHelper('dialog');
$reusable = new \Reusable();
$fs = new Filesystem();
$cmd = new \ColorOutput();
//push only vendors into the vendors array
$vendors = $reusable->getFileList($reusable->getMainDirectory('src'),true);
//select a vendor from the array
$vendor = $dialog->select(
$output,
'Select your vendor [1]: ',
$vendors,
1
);
$bundles_in_vendor = $reusable->getFileList($reusable->getMainDirectory('src/'.$vendors[$vendor]),true);
//push bundles that start with 'Site' into array
$sites = array();
foreach($bundles_in_vendor as $bundle)
{
if($reusable->startsWith($bundle,'Site'))
{
array_push($sites,$bundle);
}
}
$site_to_delete = $dialog->select(
$output,
'Select site to remove: ',
$sites,
1
);
$bundle_deletion_path = $reusable->getMainDirectory('src/'.$vendors[$vendor]).'/'.$sites[$site_to_delete];
$are_you_sure = array('yes','no');
$confirmation = $dialog->select(
$output,
'Are you sure you want to delete: '.$sites[$site_to_delete],
$are_you_sure,
1
);
if($are_you_sure[$confirmation] == 'yes')
{
echo $cmd->color('yellow','attempting to remove bundle in: '.$bundle_deletion_path);
$fs->remove($bundle_deletion_path);
//returns demo
$sitename = strtolower($sites[$site_to_delete]);
$sitename = substr($sitename,0,-6);
$sitename = substr($sitename,4);
$this->setRawSiteNameInput($sitename);
// returns acmedemo
$symlinkname = strtolower($vendors[$vendor].substr($sites[$site_to_delete],0,-6));
$this->removeSymlinks($symlinkname,$this->getRawSiteNameInput());
$this->createSetters($vendor,substr($sites[$site_to_delete],0,-6));
$this->deleteEzPublishExtension();
echo $this->getFullLegacyPath();
echo $cmd->color('green','deletion process completed.');
}
else
{
echo "deletion canceled";
die();
}
function_that_further_deletion_process();
}
这是一个 symfony2 控制台脚本,可以从特定结构中删除站点
如果这是您的问题,那是绝对安全的,因为 php 作为一种准解释语言,在终止执行时不会留下任何痕迹或人工痕迹。
如果这是一个好的做法是另一回事。我会说它可以用于测试目的,但您应该在最终代码中避免使用它。原因是它使代码难以维护。考虑其他人深入研究您的代码并试图理解其中的逻辑。人们实际上必须通过 all 代码才能偶然发现这一细节。机会是一个没有,所以你的代码的行为似乎被破坏了。
改为尝试执行以下操作之一:
抛出异常离开当前作用域。这样的异常很可能会被调用范围捕获并吞没,但它是一种清晰且可预测的 returning 方式。显然你应该记录这样的行为。
return 一个值显然超出了 "normally" 被 return 编辑的范围。因此,例如
null
或false
而不是典型值。这会强制调用作用域检查 return 值,但无论如何这都是很好的做法。重组您的代码,这样就没有理由突然终止执行。
您还没有告诉我们您的意图是什么 die
.. 因此我们无法判断您是否使用了正确的工具...
die
和它的同义词 exit
都退出脚本。如果那是你想要的,那很好。
我倾向于将 exit
用于正常操作,将 die
用于错误情况(无法正确恢复的情况,例如:无法连接到数据库)。我还为 die
使用包装器,因此如果需要,我可以记录此类事件。虽然两个命令做同样的事情,但意图不同,我想在代码中表达这个意图。
在您的示例中,我将使用 exit
。