是否可以使用静态类将静态方法链接在一起?说我想做这样的事情:

$value = TestClass::toValue(5)::add(3)::subtract(2)::add(8)::result();

。 。 。显然我希望$ value被分配数字14.这可能吗?

更新:它不起作用(你不能返回“自我” - 它不是一个实例!),但这是我的想法带给我的地方:

class TestClass {
    public static $currentValue;

    public static function toValue($value) {
        self::$currentValue = $value;
    }

    public static function add($value) {
        self::$currentValue = self::$currentValue + $value;
        return self;
    }

    public static function subtract($value) {
        self::$currentValue = self::$currentValue - $value;
        return self;
    }

    public static function result() {
        return self::$value;
    }
}

在完成这项工作之后,我认为简单地使用类实例而不是尝试链接静态函数调用(这看起来不可能,除非以上示例可以某种方式进行调整)更有意义。 / p>

有帮助吗?

解决方案

我喜欢Camilo上面提供的解决方案,主要是因为您所做的只是改变静态成员的值,并且因为您确实需要链接(即使它只是合成糖),然后实例化TestClass可能是最好的要走的路。

如果你想限制类的实例化,我建议使用Singleton模式:

class TestClass
{   
    public static $currentValue;

    private static 

我喜欢Camilo上面提供的解决方案,主要是因为您所做的只是改变静态成员的值,并且因为您确实需要链接(即使它只是合成糖),然后实例化TestClass可能是最好的要走的路。

如果你想限制类的实例化,我建议使用Singleton模式:

<*>instance = null; private function __construct () { } public static function getInstance () { if (self::

我喜欢Camilo上面提供的解决方案,主要是因为您所做的只是改变静态成员的值,并且因为您确实需要链接(即使它只是合成糖),然后实例化TestClass可能是最好的要走的路。

如果你想限制类的实例化,我建议使用Singleton模式:

<*>instance === null) { self::

我喜欢Camilo上面提供的解决方案,主要是因为您所做的只是改变静态成员的值,并且因为您确实需要链接(即使它只是合成糖),然后实例化TestClass可能是最好的要走的路。

如果你想限制类的实例化,我建议使用Singleton模式:

<*>instance = new self; } return self::

我喜欢Camilo上面提供的解决方案,主要是因为您所做的只是改变静态成员的值,并且因为您确实需要链接(即使它只是合成糖),然后实例化TestClass可能是最好的要走的路。

如果你想限制类的实例化,我建议使用Singleton模式:

<*>instance; } public function toValue($value) { self::$currentValue = $value; return $this; } public function add($value) { self::$currentValue = self::$currentValue + $value; return $this; } public function subtract($value) { self::$currentValue = self::$currentValue - $value; return $this; } public function result() { return self::$currentValue; } } // Example Usage: $result = TestClass::getInstance () ->toValue(5) ->add(3) ->subtract(2) ->add(8) ->result();

其他提示

class oop{
    public static $val;

    public static function add($var){
        static::$val+=$var;
        return new static;
    }

    public static function sub($var){
        static::$val-=$var;
        return new static;
    }

    public static function out(){
        return static::$val;
    }

    public static function init($var){
        static::$val=$var;
        return new static;      
    }
}

echo oop::init(5)->add(2)->out();

关于php5.3的小疯狂代码......只是为了好玩。

namespace chaining;
class chain
    {
    static public function one()
        {return get_called_class();}

    static public function two()
        {return get_called_class();}
    }

${${${${chain::one()} = chain::two()}::one()}::two()}::one();

使用php7,您将能够使用所需的语法,因为新的统一变量语法

<?php

abstract class TestClass {

    public static $currentValue;

    public static function toValue($value) {
        self::$currentValue = $value;
        return __CLASS__;
    }

    public static function add($value) {
        self::$currentValue = self::$currentValue + $value;
        return __CLASS__;
    }

    public static function subtract($value) {
        self::$currentValue = self::$currentValue - $value;
        return __CLASS__;
    }

    public static function result() {
        return self::$currentValue;
    }

}

$value = TestClass::toValue(5)::add(3)::subtract(2)::add(8)::result();
echo $value;

演示

如果toValue(x)返回一个对象,你可以这样做:

$value = TestClass::toValue(5)->add(3)->substract(2)->add(8);

假设toValue返回一个对象的新实例,并且每个next方法都会改变它,返回$ this的实例。

您始终可以将First方法用作静态方法,将剩余的方法用作实例方法:

$value = Math::toValue(5)->add(3)->subtract(2)->add(8)->result();

或者更好:

 $value = Math::eval(Math::value(5)->add(3)->subtract(2)->add(8));

class Math {
     public $operation;
     public $operationValue;
     public $args;
     public $allOperations = array();

     public function __construct($aOperation, $aValue, $theArgs)
     {
       $this->operation = $aOperation;
       $this->operationValue = $aValue;
       $this->args = $theArgs;
     }

     public static function eval($math) {
       if(strcasecmp(get_class($math), "Math") == 0){
            $newValue = $math->operationValue;
            foreach ($math->allOperations as $operationKey=>$currentOperation) {
                switch($currentOperation->operation){
                    case "add":
                         $newvalue = $currentOperation->operationValue + $currentOperation->args;
                         break;
                    case "subtract":
                         $newvalue = $currentOperation->operationValue - $currentOperation->args;
                         break;
                }
            }
            return $newValue;
       }
       return null;
     }

     public function add($number){
         $math = new Math("add", null, $number);
         $this->allOperations[count($this->allOperations)] &= $math;
         return $this;
     }

     public function subtract($number){
         $math = new Math("subtract", null, $number);
         $this->allOperations[count($this->allOperations)] &= $math;
         return $this;
     }

     public static function value($number){
         return new Math("value", $number, null);
     }
 }

只是一个FYI ..我把它写在了我的头顶(就在网站上)。所以,它可能无法运行,但这就是主意。我本可以对eval做一个递归方法调用,但我认为这可能更简单。如果您希望我详细说明或提供任何其他帮助,请与我们联系。

从技术上讲,您可以在PHP 7+中的 $ object :: method()之类的实例上调用静态方法,因此返回一个新实例应该可以替代 return self 确实有效。

final class TestClass {
    public static $currentValue;

    public static function toValue($value) {
        self::$currentValue = $value;
        return new static();
    }

    public static function add($value) {
        self::$currentValue = self::$currentValue + $value;
        return new static();
    }

    public static function subtract($value) {
        self::$currentValue = self::$currentValue - $value;
        return new static();
    }

    public static function result() {
        return self::$currentValue;
    }
}

$value = TestClass::toValue(5)::add(3)::subtract(2)::add(8)::result();

var_dump($value);

输出 int(14)

这与使用其他答案中的 __ CLASS __ 相同。我宁愿希望没有人决定实际使用这些形式的API,但你要求它。

简而言之......不。 :)解析运算符(::)适用于TetsClass :: toValue(5)部分,但之后的所有内容都只会产生语法错误。

一旦命名空间在5.3中实现,你就可以拥有“链接”状态。 ::运算符,但所有这些都是向下钻取命名空间树;在这样的事情中,不可能有方法。

可以做的最好的事情

class S
{
    public static function  __callStatic($name,$args)
    {
        echo 'called S::'.$name . '( )<p>';
        return '_t';
    }
}

可以做的最好的事情

<*>t='S'; ${${S::X()}::F()}::C();

这更准确,更容易,并且对读取更友好(允许代码完成)

class Calculator
{   
    public static $value = 0;

    protected static $onlyInstance;

    protected function __construct () 
    {
        // disable creation of public instances 
    }

    protected static function getself()
    {
        if (static::$onlyInstance === null) 
        {
            static::$onlyInstance = new Calculator;
        }

        return static::$onlyInstance;
    }

    /**
     * add to value
     * @param numeric $num 
     * @return \Calculator
     */
    public static function add($num) 
    {
        static::$value += $num;
        return static::getself();
    }

    /**
     * substruct
     * @param string $num
     * @return \Calculator
     */
    public static function subtract($num) 
    {
        static::$value -= $num;
        return static::getself();
    }

    /**
     * multiple by
     * @param string $num
     * @return \Calculator
     */
    public static function multiple($num) 
    {
        static::$value *= $num;
        return static::getself();
    }

    /**
     * devide by
     * @param string $num
     * @return \Calculator
     */
    public static function devide($num) 
    {
        static::$value /= $num;
        return static::getself();
    }

    public static function result()
    {
        return static::$value;
    }
}

示例:

echo Calculator::add(5)
        ->subtract(2)
        ->multiple(2.1)
        ->devide(10)
    ->result();

结果:0.63

不,这不起作用。 :: 运算符需要求值回一个类,所以在 TestClass :: toValue(5)求值之后, :: add(3) method只能评估最后一个的答案。

所以如果 toValue(5)返回整数5,你基本上会调用 int(5):: add(3),这显然是一个错误。

我从类新的Instance或Static方法找到方法链的最简单方法如下所示。我在这里使用了Late Static Binding,我非常喜欢这个解决方案。

我创建了一个实用程序,可以在Laravel中使用tostr在下一页上发送多个用户通知。

<?php

namespace App\Utils;

use Session;

use Illuminate\Support\HtmlString;

class Toaster
{
    private static $options = [

        "closeButton" => false,

        "debug" => false,

        "newestOnTop" => false,

        "progressBar" => false,

        "positionClass" => "toast-top-right",

        "preventDuplicates" => false,

        "onclick" => null,

        "showDuration" => "3000",

        "hideDuration" => "1000",

        "timeOut" => "5000",

        "extendedTimeOut" => "1000",

        "showEasing" => "swing",

        "hideEasing" => "linear",

        "showMethod" => "fadeIn",

        "hideMethod" => "fadeOut"
    ];

    private static $toastType = "success";

    private static $instance;

    private static $title;

    private static $message;

    private static $toastTypes = ["success", "info", "warning", "error"];

    public function __construct($options = [])
    {
        self::$options = array_merge(self::$options, $options);
    }

    public static function setOptions(array $options = [])
    {
        self::$options = array_merge(self::$options, $options);

        return self::getInstance();
    }

    public static function setOption($option, $value)
    {
        self::$options[$option] = $value;

        return self::getInstance();
    }

    private static function getInstance()
    {
        if(empty(self::$instance) || self::$instance === null)
        {
            self::setInstance();
        }

        return self::$instance;
    }

    private static function setInstance()
    {
        self::$instance = new static();
    }

    public static function __callStatic($method, $args)
    {
        if(in_array($method, self::$toastTypes))
        {
            self::$toastType = $method;

            return self::getInstance()->initToast($method, $args);
        }

        throw new \Exception("Ohh my god. That toast doesn't exists.");
    }

    public function __call($method, $args)
    {
        return self::__callStatic($method, $args);
    }

    private function initToast($method, $params=[])
    {
        if(count($params)==2)
        {
            self::$title = $params[0];

            self::$message = $params[1];
        }
        elseif(count($params)==1)
        {
            self::$title = ucfirst($method);

            self::$message = $params[0];
        }

        $toasters = [];

        if(Session::has('toasters'))
        {
            $toasters = Session::get('toasters');
        }

        $toast = [

            "options" => self::$options,

            "type" => self::$toastType,

            "title" => self::$title,

            "message" => self::$message
        ];

        $toasters[] = $toast;

        Session::forget('toasters');

        Session::put('toasters', $toasters);

        return $this;
    }

    public static function renderToasters()
    {
        $toasters = Session::get('toasters');

        $string = '';

        if(!empty($toasters))
        {
            $string .= '<script type="application/javascript">';

            $string .= "$(function() {\n";

            foreach ($toasters as $toast)
            {
                $string .= "\n toastr.options = " . json_encode($toast['options'], JSON_PRETTY_PRINT) . ";";

                $string .= "\n toastr['{$toast['type']}']('{$toast['message']}', '{$toast['title']}');";
            }

            $string .= "\n});";

            $string .= '</script>';
        }

        Session::forget('toasters');

        return new HtmlString($string);
    }
}

这将如下工作。

Toaster::success("Success Message", "Success Title")

    ->setOption('showDuration', 5000)

    ->warning("Warning Message", "Warning Title")

    ->error("Error Message");

使用静态属性进行方法链接的全功能示例:

<?php


class Response
{
    static protected $headers = [];
    static protected $http_code = 200;
    static protected $http_code_msg = '';
    static protected $instance = NULL;


    protected function __construct() { }

    static function getInstance(){
        if(static::$instance == NULL){
            static::$instance = new static();
        }
        return static::$instance;
    }

    public function addHeaders(array $headers)
    {
        static::$headers = $headers;
        return static::getInstance();
    }

    public function addHeader(string $header)
    {
        static::$headers[] = $header;
        return static::getInstance();
    }

    public function code(int $http_code, string $msg = NULL)
    {
        static::$http_code_msg = $msg;
        static::$http_code = $http_code;
        return static::getInstance();
    }

    public function send($data, int $http_code = NULL){
        $http_code = $http_code != NULL ? $http_code : static::$http_code;

        if ($http_code != NULL)
            header(trim("HTTP/1.0 ".$http_code.' '.static::$http_code_msg));

        if (is_array($data) || is_object($data))
            $data = json_encode($data);

        echo $data; 
        exit();     
    }

    function sendError(string $msg_error, int $http_code = null){
        $this->send(['error' => $msg_error], $http_code);
    }
}

使用示例:

Response::getInstance()->code(400)->sendError("Lacks id in request");

使用PHP 7!如果您的网络提供商不能 - >改变提供者!不要锁定过去。

final class TestClass {
    public static $currentValue;

    public static function toValue($value) {
        self::$currentValue = $value;
        return __CLASS__;
    }

    public static function add($value) {
        self::$currentValue = self::$currentValue + $value;
        return __CLASS__;
    }

    public static function subtract($value) {
        self::$currentValue = self::$currentValue - $value;
        return __CLASS__;
    }

    public static function result() {
        return self::$currentValue;
    }
}

使用非常简单:

$value = TestClass::toValue(5)::add(3)::subtract(2)::add(8)::result();

var_dump($value);

返回(或抛出错误):

int(14)

已完成合同。

规则一:最进化和可维护的总是更好。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top