Joyber 发布的文章
php代替eval执行字符串数学表达式StrToBcmath
<?php
// 字符串转BcMath计算结果
class StrToBcmath {
/**
* @var int
*/
private $scale; // 精度
/**
* @var mixed // 是否输出计算过程
*/
private $isecho;
/**
* @param $scale // 可选,精度,默认值:8
* @param $isecho // 可选,是否输出计算过程,默认值:false
*/
public function __construct($scale = 8, $isecho = false) {
$this->scale = $scale;
$this->isecho = $isecho;
}
// 主方法
/**
* @param $expression // 复杂运算表达式
* @param $scale // 精度
* @param $isRecursive // 是否递归,递归时不输出计算过程
*/
public function of($expression, $scale = '', $isRecursive = false) {
$scale = $scale ?: $this->scale;
// 原始表达式
if (!$isRecursive && $this->isecho) {
echo $expression . "\n";
}
// 去除空格
if (!$isRecursive) {
$expression = str_replace(' ', '', $expression);
}
//避免$expression=0,出现InvalidArgumentException错误
if (is_numeric($expression) && $expression == 0) return 0;
// 如果输入的表达式为空或者包含非法字符,则抛出异常
if (empty($expression) || preg_match('/[^0-9\.\+\-\*\/\(\)]/', $expression)) {
throw new \InvalidArgumentException('表达式错误,仅支持+,-,*,/,**,(),数字:' . $expression);
}
// 使用正则表达式匹配表达式中的括号
while (preg_match('/\(([^\(\)]+)\)/', $expression, $matches)) {
// 计算括号中的表达式
$res = $this->of($matches[1], $scale, true);
// 将没有括号的表达式替换到原表达式中
$expression = str_replace('(' . $matches[1] . ')', $res, $expression);
if ($this->isecho) {
echo '=' . $expression . "\n";
}
}
// 处理指数运算
while (preg_match('/(\d+(\.\d+)?)(\*\*)(\d+(\.\d+)?)/', $expression, $matches)) {
$res = $this->basic($matches[0], $scale);
$expression = str_replace($matches[0], $res, $expression);
if (!$isRecursive && $this->isecho) {
echo '=' . $expression . "\n";
}
}
// 处理乘法、除法
while (preg_match('/(\d+(\.\d+)?)([\/*])(\d+(\.\d+)?)/', $expression, $matches)) {
$res = $this->basic($matches[0], $scale);
$expression = str_replace($matches[0], $res, $expression);
if (!$isRecursive && $this->isecho) {
echo '=' . $expression . "\n";
}
}
// 处理加法和减法
while (preg_match('/(-?\d+(\.\d+)?)([+\-])(-?\d+(\.\d+)?)/', $expression, $matches)) {
$res = $this->basic($matches[0], $scale);
$expression = str_replace($matches[0], $res, $expression);
if (!$isRecursive && $this->isecho) {
echo '=' . $expression . "\n";
}
}
// 返回计算结果
return $expression;
}
// 基本的四则运算
/**
* @param $expression // 基本的四则运算表达式
* @param $scale // 精度
*/
public function basic($expression, $scale = '') {
$scale = $scale ?: $this->scale;
// 使用正则表达式匹配表达式中的两个操作数和一个运算符
if (!preg_match('/^(-?\d+(\.\d+)?)([\/*+-]|(\*\*))(-?\d+(\.\d+)?)$/', $expression, $matches)) {
throw new \InvalidArgumentException('表达式错误,不符合基本的四则运算:' . $expression);
}
// dump($matches);
// 根据运算符调用对应的 bcmath 函数
$operator = $matches[3];
$a = strval($matches[1]);
$b = strval($matches[5]);
// if ($this->isecho) {
// echo '【处理运算符】' . $a . $operator . $b . "\n";
// }
try {
switch ($operator) {
case '+':
return bcadd($a, $b, $scale);
case '-':
return bcsub($a, $b, $scale);
case '*':
return bcmul($a, $b, $scale);
case '/':
if ($b == 0) {
throw new \InvalidArgumentException('除数不能为零:' . $a . $operator . $b);
}
return bcdiv($a, $b, $scale);
case '**':
if (strpos($b, '.') !== false) {
if ((int) $b == $b) {
$b = (int) $b;
} else {
throw new \InvalidArgumentException('指数不能为小数:' . $a . $operator . $b);
}
}
return bcpow($a, $b, $scale);
default:
throw new \InvalidArgumentException('未知的运算符:' . $a . $operator . $b);
}
} catch (\Exception $e) {
throw new \InvalidArgumentException($e->getMessage());
}
}
}
yii ccomponent 类定义
class CComponent
{
private $_e;
private $_m;
/**
* Returns a property value, an event handler list or a behavior based on its name.
* Do not call this method. This is a PHP magic method that we override
* to allow using the following syntax to read a property or obtain event handlers:
* <pre>
* $value=$component->propertyName;
* $handlers=$component->eventName;
* </pre>
* @param string $name the property name or event name
* @return mixed the property value, event handlers attached to the event, or the named behavior
* @throws CException if the property or event is not defined
* @see __set
*/
public function __get($name)
{
$getter='get'.$name;
if(method_exists($this,$getter))
return $this->$getter();
elseif(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
{
// duplicating getEventHandlers() here for performance
$name=strtolower($name);
if(!isset($this->_e[$name]))
$this->_e[$name]=new CList;
return $this->_e[$name];
}
elseif(isset($this->_m[$name]))
return $this->_m[$name];
elseif(is_array($this->_m))
{
foreach($this->_m as $object)
{
if($object->getEnabled() && (property_exists($object,$name) || $object->canGetProperty($name)))
return $object->$name;
}
}
throw new CException(Yii::t('yii','Property "{class}.{property}" is not defined.',
array('{class}'=>get_class($this), '{property}'=>$name)));
}
/**
* Sets value of a component property.
* Do not call this method. This is a PHP magic method that we override
* to allow using the following syntax to set a property or attach an event handler
* <pre>
* $this->propertyName=$value;
* $this->eventName=$callback;
* </pre>
* @param string $name the property name or the event name
* @param mixed $value the property value or callback
* @return mixed
* @throws CException if the property/event is not defined or the property is read only.
* @see __get
*/
public function __set($name,$value)
{
$setter='set'.$name;
if(method_exists($this,$setter))
return $this->$setter($value);
elseif(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
{
// duplicating getEventHandlers() here for performance
$name=strtolower($name);
if(!isset($this->_e[$name]))
$this->_e[$name]=new CList;
return $this->_e[$name]->add($value);
}
elseif(is_array($this->_m))
{
foreach($this->_m as $object)
{
if($object->getEnabled() && (property_exists($object,$name) || $object->canSetProperty($name)))
return $object->$name=$value;
}
}
if(method_exists($this,'get'.$name))
throw new CException(Yii::t('yii','Property "{class}.{property}" is read only.',
array('{class}'=>get_class($this), '{property}'=>$name)));
else
throw new CException(Yii::t('yii','Property "{class}.{property}" is not defined.',
array('{class}'=>get_class($this), '{property}'=>$name)));
}
/**
* Checks if a property value is null.
* Do not call this method. This is a PHP magic method that we override
* to allow using isset() to detect if a component property is set or not.
* @param string $name the property name or the event name
* @return boolean
*/
public function __isset($name)
{
$getter='get'.$name;
if(method_exists($this,$getter))
return $this->$getter()!==null;
elseif(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
{
$name=strtolower($name);
return isset($this->_e[$name]) && $this->_e[$name]->getCount();
}
elseif(is_array($this->_m))
{
if(isset($this->_m[$name]))
return true;
foreach($this->_m as $object)
{
if($object->getEnabled() && (property_exists($object,$name) || $object->canGetProperty($name)))
return $object->$name!==null;
}
}
return false;
}
/**
* Sets a component property to be null.
* Do not call this method. This is a PHP magic method that we override
* to allow using unset() to set a component property to be null.
* @param string $name the property name or the event name
* @throws CException if the property is read only.
* @return mixed
*/
public function __unset($name)
{
$setter='set'.$name;
if(method_exists($this,$setter))
$this->$setter(null);
elseif(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
unset($this->_e[strtolower($name)]);
elseif(is_array($this->_m))
{
if(isset($this->_m[$name]))
$this->detachBehavior($name);
else
{
foreach($this->_m as $object)
{
if($object->getEnabled())
{
if(property_exists($object,$name))
return $object->$name=null;
elseif($object->canSetProperty($name))
return $object->$setter(null);
}
}
}
}
elseif(method_exists($this,'get'.$name))
throw new CException(Yii::t('yii','Property "{class}.{property}" is read only.',
array('{class}'=>get_class($this), '{property}'=>$name)));
}
/**
* Calls the named method which is not a class method.
* Do not call this method. This is a PHP magic method that we override
* to implement the behavior feature.
* @param string $name the method name
* @param array $parameters method parameters
* @throws CException if current class and its behaviors do not have a method or closure with the given name
* @return mixed the method return value
*/
public function __call($name,$parameters)
{
if($this->_m!==null)
{
foreach($this->_m as $object)
{
if($object->getEnabled() && method_exists($object,$name))
return call_user_func_array(array($object,$name),$parameters);
}
}
if(class_exists('Closure', false) && ($this->canGetProperty($name) || property_exists($this, $name)) && $this->$name instanceof Closure)
return call_user_func_array($this->$name, $parameters);
throw new CException(Yii::t('yii','{class} and its behaviors do not have a method or closure named "{name}".',
array('{class}'=>get_class($this), '{name}'=>$name)));
}
/**
* Returns the named behavior object.
* The name 'asa' stands for 'as a'.
* @param string $behavior the behavior name
* @return IBehavior the behavior object, or null if the behavior does not exist
*/
public function asa($behavior)
{
return isset($this->_m[$behavior]) ? $this->_m[$behavior] : null;
}
/**
* Attaches a list of behaviors to the component.
* Each behavior is indexed by its name and should be an instance of
* {@link IBehavior}, a string specifying the behavior class, or an
* array of the following structure:
* <pre>
* array(
* 'class'=>'path.to.BehaviorClass',
* 'property1'=>'value1',
* 'property2'=>'value2',
* )
* </pre>
* @param array $behaviors list of behaviors to be attached to the component
*/
public function attachBehaviors($behaviors)
{
foreach($behaviors as $name=>$behavior)
$this->attachBehavior($name,$behavior);
}
/**
* Detaches all behaviors from the component.
*/
public function detachBehaviors()
{
if($this->_m!==null)
{
foreach($this->_m as $name=>$behavior)
$this->detachBehavior($name);
$this->_m=null;
}
}
/**
* Attaches a behavior to this component.
* This method will create the behavior object based on the given
* configuration. After that, the behavior object will be initialized
* by calling its {@link IBehavior::attach} method.
* @param string $name the behavior's name. It should uniquely identify this behavior.
* @param mixed $behavior the behavior configuration. This is passed as the first
* parameter to {@link YiiBase::createComponent} to create the behavior object.
* You can also pass an already created behavior instance (the new behavior will replace an already created
* behavior with the same name, if it exists).
* @return IBehavior the behavior object
*/
public function attachBehavior($name,$behavior)
{
if(!($behavior instanceof IBehavior))
$behavior=Yii::createComponent($behavior);
$behavior->setEnabled(true);
$behavior->attach($this);
return $this->_m[$name]=$behavior;
}
/**
* Detaches a behavior from the component.
* The behavior's {@link IBehavior::detach} method will be invoked.
* @param string $name the behavior's name. It uniquely identifies the behavior.
* @return IBehavior the detached behavior. Null if the behavior does not exist.
*/
public function detachBehavior($name)
{
if(isset($this->_m[$name]))
{
$this->_m[$name]->detach($this);
$behavior=$this->_m[$name];
unset($this->_m[$name]);
return $behavior;
}
}
/**
* Enables all behaviors attached to this component.
*/
public function enableBehaviors()
{
if($this->_m!==null)
{
foreach($this->_m as $behavior)
$behavior->setEnabled(true);
}
}
/**
* Disables all behaviors attached to this component.
*/
public function disableBehaviors()
{
if($this->_m!==null)
{
foreach($this->_m as $behavior)
$behavior->setEnabled(false);
}
}
/**
* Enables an attached behavior.
* A behavior is only effective when it is enabled.
* A behavior is enabled when first attached.
* @param string $name the behavior's name. It uniquely identifies the behavior.
*/
public function enableBehavior($name)
{
if(isset($this->_m[$name]))
$this->_m[$name]->setEnabled(true);
}
/**
* Disables an attached behavior.
* A behavior is only effective when it is enabled.
* @param string $name the behavior's name. It uniquely identifies the behavior.
*/
public function disableBehavior($name)
{
if(isset($this->_m[$name]))
$this->_m[$name]->setEnabled(false);
}
/**
* Determines whether a property is defined.
* A property is defined if there is a getter or setter method
* defined in the class. Note, property names are case-insensitive.
* @param string $name the property name
* @return boolean whether the property is defined
* @see canGetProperty
* @see canSetProperty
*/
public function hasProperty($name)
{
return method_exists($this,'get'.$name) || method_exists($this,'set'.$name);
}
/**
* Determines whether a property can be read.
* A property can be read if the class has a getter method
* for the property name. Note, property name is case-insensitive.
* @param string $name the property name
* @return boolean whether the property can be read
* @see canSetProperty
*/
public function canGetProperty($name)
{
return method_exists($this,'get'.$name);
}
/**
* Determines whether a property can be set.
* A property can be written if the class has a setter method
* for the property name. Note, property name is case-insensitive.
* @param string $name the property name
* @return boolean whether the property can be written
* @see canGetProperty
*/
public function canSetProperty($name)
{
return method_exists($this,'set'.$name);
}
/**
* Determines whether an event is defined.
* An event is defined if the class has a method named like 'onXXX'.
* Note, event name is case-insensitive.
* @param string $name the event name
* @return boolean whether an event is defined
*/
public function hasEvent($name)
{
return !strncasecmp($name,'on',2) && method_exists($this,$name);
}
/**
* Checks whether the named event has attached handlers.
* @param string $name the event name
* @return boolean whether an event has been attached one or several handlers
*/
public function hasEventHandler($name)
{
$name=strtolower($name);
return isset($this->_e[$name]) && $this->_e[$name]->getCount()>0;
}
/**
* Returns the list of attached event handlers for an event.
* @param string $name the event name
* @return CList list of attached event handlers for the event
* @throws CException if the event is not defined
*/
public function getEventHandlers($name)
{
if($this->hasEvent($name))
{
$name=strtolower($name);
if(!isset($this->_e[$name]))
$this->_e[$name]=new CList;
return $this->_e[$name];
}
else
throw new CException(Yii::t('yii','Event "{class}.{event}" is not defined.',
array('{class}'=>get_class($this), '{event}'=>$name)));
}
/**
* Attaches an event handler to an event.
*
* An event handler must be a valid PHP callback, i.e., a string referring to
* a global function name, or an array containing two elements with
* the first element being an object and the second element a method name
* of the object.
*
* An event handler must be defined with the following signature,
* <pre>
* function handlerName($event) {}
* </pre>
* where $event includes parameters associated with the event.
*
* This is a convenient method of attaching a handler to an event.
* It is equivalent to the following code:
* <pre>
* $component->getEventHandlers($eventName)->add($eventHandler);
* </pre>
*
* Using {@link getEventHandlers}, one can also specify the execution order
* of multiple handlers attaching to the same event. For example:
* <pre>
* $component->getEventHandlers($eventName)->insertAt(0,$eventHandler);
* </pre>
* makes the handler to be invoked first.
*
* @param string $name the event name
* @param callback $handler the event handler
* @throws CException if the event is not defined
* @see detachEventHandler
*/
public function attachEventHandler($name,$handler)
{
$this->getEventHandlers($name)->add($handler);
}
/**
* Detaches an existing event handler.
* This method is the opposite of {@link attachEventHandler}.
* @param string $name event name
* @param callback $handler the event handler to be removed
* @return boolean if the detachment process is successful
* @see attachEventHandler
*/
public function detachEventHandler($name,$handler)
{
if($this->hasEventHandler($name))
return $this->getEventHandlers($name)->remove($handler)!==false;
else
return false;
}
/**
* Raises an event.
* This method represents the happening of an event. It invokes
* all attached handlers for the event.
* @param string $name the event name
* @param CEvent $event the event parameter
* @throws CException if the event is undefined or an event handler is invalid.
*/
public function raiseEvent($name,$event)
{
$name=strtolower($name);
if(isset($this->_e[$name]))
{
foreach($this->_e[$name] as $handler)
{
if(is_string($handler))
call_user_func($handler,$event);
elseif(is_callable($handler,true))
{
if(is_array($handler))
{
// an array: 0 - object, 1 - method name
list($object,$method)=$handler;
if(is_string($object)) // static method call
call_user_func($handler,$event);
elseif(method_exists($object,$method))
$object->$method($event);
else
throw new CException(Yii::t('yii','Event "{class}.{event}" is attached with an invalid handler "{handler}".',
array('{class}'=>get_class($this), '{event}'=>$name, '{handler}'=>$handler[1])));
}
else // PHP 5.3: anonymous function
call_user_func($handler,$event);
}
else
throw new CException(Yii::t('yii','Event "{class}.{event}" is attached with an invalid handler "{handler}".',
array('{class}'=>get_class($this), '{event}'=>$name, '{handler}'=>gettype($handler))));
// stop further handling if param.handled is set true
if(($event instanceof CEvent) && $event->handled)
return;
}
}
elseif(YII_DEBUG && !$this->hasEvent($name))
throw new CException(Yii::t('yii','Event "{class}.{event}" is not defined.',
array('{class}'=>get_class($this), '{event}'=>$name)));
}
/**
* Evaluates a PHP expression or callback under the context of this component.
*
* Valid PHP callback can be class method name in the form of
* array(ClassName/Object, MethodName), or anonymous function (only available in PHP 5.3.0 or above).
*
* If a PHP callback is used, the corresponding function/method signature should be
* <pre>
* function foo($param1, $param2, ..., $component) { ... }
* </pre>
* where the array elements in the second parameter to this method will be passed
* to the callback as $param1, $param2, ...; and the last parameter will be the component itself.
*
* If a PHP expression is used, the second parameter will be "extracted" into PHP variables
* that can be directly accessed in the expression. See {@link http://us.php.net/manual/en/function.extract.php PHP extract}
* for more details. In the expression, the component object can be accessed using $this.
*
* A PHP expression can be any PHP code that has a value. To learn more about what an expression is,
* please refer to the {@link http://www.php.net/manual/en/language.expressions.php php manual}.
*
* @param mixed $_expression_ a PHP expression or PHP callback to be evaluated.
* @param array $_data_ additional parameters to be passed to the above expression/callback.
* @return mixed the expression result
* @since 1.1.0
*/
public function evaluateExpression($_expression_,$_data_=array())
{
if(is_string($_expression_))
{
extract($_data_);
try
{
return eval('return ' . $_expression_ . ';');
}
catch (ParseError $e)
{
return false;
}
}
else
{
$_data_[]=$this;
return call_user_func_array($_expression_, array_values($_data_));
}
}
} 深入理解PHP配置文件中3个超时时间设置
在PHP应用中,超时时间的设置对于应用的性能和稳定性至关重要。超时时间配置不当可能导致应用响应缓慢、资源占用过高,甚至引发服务崩溃。本文将详细解析PHP配置文件php.ini和php-fpm.conf中的超时时间设置,帮助读者深入理解这些设置的作用、影响以及如何合理配置。
一、php.ini中的超时时间设置
max_execution_time
max_execution_time 是php.ini中的一个重要设置,它定义了PHP脚本的最大执行时间。当脚本运行时间超过这个值时,PHP会终止脚本的执行并返回一个致命错误。这个设置对于防止恶意脚本或无限循环脚本占用过多资源非常有用。
默认情况下,max_execution_time 的值为30秒。在实际应用中,我们可以根据应用的需求和性能要求来合理设置这个值。需要注意的是,这个设置只影响PHP脚本本身的执行时间,不包括脚本执行过程中可能发生的数据库查询、文件操作等外部操作的时间。
set_time_limit() 可以在php代码中更改执行时间 max_execution_time 的定义。
implicit_flush
implicit_flush 是一个影响输出缓冲设置的选项。当implicit_flush设置为On时,PHP会在每次输出内容时自动刷新输出缓冲区,这样可以确保用户能够实时看到输出的内容。然而,频繁的刷新输出缓冲区可能会降低应用的性能。因此,在需要实时输出内容的情况下,我们可以将implicit_flush设置为On;在其他情况下,建议将其设置为Off以提高性能。
二、php-fpm.conf中的超时时间设置
request_terminate_timeout
[www] 范围
request_terminate_timeout 是php-fpm.conf中的一个设置,它定义了PHP-FPM进程在处理请求时的最大执行时间。当请求的处理时间超过这个值时,PHP-FPM会强制终止该请求并返回一个错误。这个设置有助于防止长时间运行的请求占用过多的资源。
默认情况下,request_terminate_timeout 的值为0,表示禁用超时限制。在实际应用中,我们可以根据应用的需求和性能要求来合理设置这个值。需要注意的是,这个设置的值应该大于max_execution_time的值,以确保PHP脚本有足够的时间来执行。
process_control_timeout
php-fpm 全局
process_control_timeout 是php-fpm.conf中的另一个重要设置,它定义了PHP-FPM进程控制操作的超时时间。当PHP-FPM需要启动、重启或关闭子进程时,如果超过了这个时间限制,PHP-FPM会放弃该操作并返回一个错误。这个设置有助于防止PHP-FPM进程控制操作因为各种原因(如资源不足、网络延迟等)而无限期地等待。
默认情况下,process_control_timeout 的值为0,表示禁用超时限制。然而,在实际应用中,我们建议设置一个合理的值来确保PHP-FPM进程控制操作的稳定性和可靠性。
三、总结
通过本文的解析,我们深入了解了PHP配置文件php.ini和php-fpm.conf中的超时时间设置。这些设置对于提高PHP应用的性能和稳定性具有重要意义。在实际应用中,我们应该根据应用的需求和性能要求来合理配置这些值,以确保应用的正常运行和高效性能。同时,我们还需要关注这些设置可能带来的潜在风险和问题,并采取相应的措施来避免和解决这些问题。
希望本文能够帮助读者更好地理解PHP配置文件中的超时时间设置,并为实际应用中的配置提供参考和指导。
收藏 国内外服务器环境管理工具
管理面板
国内版
宝塔最新的免费面板:http://www.bt.cn/(国外版本 :https://aapanel.com)
AMH – 4.2版免费:http://amh.sh/
WDCP 老牌免费面板:http://www.wdlinux.cn/bbs/(近来爆出严重安全漏洞)
Kangle老牌免费面板:http://www.kanglesoft.com/
自己的路 – 支持freeBSD:http://www.zijidelu.org/
国外版
VestaCP:http://vestacp.com/ (比较推荐的面板,自带中文)
Kloxo-MR:https://github.com/mustafaramadhan/kloxo/ (7.0真的很强大,很好看,很实用,有中文包)
Webmin/Virtualmin:http://www.webmin.com/virtualmin.html (很稳定,很安全,自带中文)
Ispconfig:https://github.com/dclardy64/ISPConfig-3-Debian-Installer (官网没看懂这是一键包,有中文包)
i-MSCP:http://i-mscp.net/ (简单易用,自带中文)
EasySCP:http://www.easyscp.net/ (和i-MSCP一样来自Ispconfig,自带中文)
Ajenti:http://ajenti.org/ (轻量级,类似Webmin,自带中文)
zPanel(sentora):http://www.zpanelcp.com/ http://www.sentora.org/(支持win,有中文包)
centos webpanel:http://centos-webpanel.com/ (据说比较有发展前途)
Froxlor:http://www.froxlor.org/ (很轻量的,适应各种环境)
AlternC:https://alternc.org/ (简单)
Easy Hosting Control Panel:http://ehcp.net/ (还不错的面板,有第三方汉化包)
CyberPanel面板:http://docs.cyberpanel.net/doku.php (目前只支持Centos 7.x)
宝塔英文版?http://www.aapanel.com
runcloud.io面板:https://runcloud.io (有免费版和付费版)
froxlor面板:https://www.froxlor.org/ (面板没有汉化)
一键安装包
国内版
http://lnmp.org/ (用的人很多,适应性很强)
https://oneinstack.com/ (用户也很多,博主一直使用这个)
http://teddysun.com/lamp (很好用的LAMP一键包) http://teddysun.com/lamp-yum (适合小内存≥64M)
http://bbs.aliyun.com/read/151729.html (阿里云论坛看到的)
http://blog.linuxeye.com/31.html (多种配置,软件较新)
http://lnmpp.net/ (支持postgresql,支持ARM)
http://www.hhvmc.com/thread-17-1-1.html (有hhvm的一键包)
http://shuang.ca/llnmp/ http://llsmp.cn/(有LiteSpeed的一键包)
https://www.lxconfig.com/thread-69-1-1.html (有openresty的一键包)
http://blog.7qy.com/html/1575.html (有cherokee的一键包)
http://lamp.phpstudy.net/ (有Lighttpd的一键包)
http://www.upupw.net/ (Windows平台环境搭建)
https://www.appnode.com (免费版不支持面板)
http://www.ltmp.cc/ (LTMP支持CentOS/RadHat)
http://bet.xrbk.top/ (BET面板 支持CentOS)
国外版
http://centminmod.com/ (据说很适合wordpress)
https://vpssim.com/ (很强大的一键包)
http://tuxlite.com/ (适用于Debian系列)
https://github.com/Xeoncross/lowendscript (lowendscript演变来的)
https://github.com/alexandreteles/monkeyServer(Monkey Web Server轻量级的web服务器) 作者:账号已注销 https://www.bilibili.com/read/cv20507364/