V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
HowToMakeLove
V2EX  ›  程序员

喜欢 Rust 的风格,写一个 PHP 的 Option 类

  •  
  •   HowToMakeLove · 2018-09-12 18:16:03 +08:00 · 1752 次点击
    这是一个创建于 2296 天前的主题,其中的信息可能已经有所发展或是发生改变。

    第一次分享东西

    项目地址: https://github.com/lisqorz/option

    除了这些,其实还想在里面加上 PHP 的 标准库方法,这样就可以更加函数式了

    小例子

    case 1

    // Option
    $res = Some($db->get())->expect(new \Exception("msg"));
    
    // native
    $res = $db->get();
    if (is_null($res)) {
        throw new \Exception("msg");
    }
    

    case2

    // Option
    $_POST["hello"] = null;
    Some($_POST['hello'])->unwrapOr("hi"); // hi
    $_POST["hello"] = "hello";
    Some($_POST['hello'])->unwrapOr("hi"); // hello
    
    // ... but we have $_POST["hello"]??"hi" 2333
    

    Case3

    // scenario
    $obj = new Obj();
    $obj->attr = null; // attr is Object;
    
    // Option
    
    // None
    $attr = Some($obj->attr)->andThen(function($attr){
    	return "";
    })->unwrapOr("no success");
    
    //Some
    $attr = Some(1)->andThen(function($attr){
        return null;
    })->unwrapOr("no success");
    
    
    // native
    $attr = "no success";
    if ($obj->attr) {
       $attr = (function($attr){return ""; })()
    }
    if (!$attr) {
        $attr = "no success";
    }
    
    第 1 条附言  ·  2018-09-13 13:08:14 +08:00

    添加一个小例子,并不是用来声明Option有多好,而是想分享一下想法,如果有其它想法,可以一起延伸、讨论 case 0

    Native
    try {
        $pdo = new PDO($db['dsn'], $db['username'], $db['password'], $options);
    } catch (PDOException $e) {
        throw new PDOException('数据库连接失败:' . $e->getMessage());
    }
    
    Option
    /** @var PDO $conn */
    Some(!$pdo->errorCode())->expect(new PDOException("数据库链接失败" . $pdo->errorCode()));
    
    Native
    $statement = $pdo->query("select count(id) from link");
    $cnt = 0;
    if (!$statement) {
        $cnt = $statement->rowCount();
    }
    
    Option
    $cnt = Some($pdo->query("select count(id) from link"))->andThen(function ($statement) {
        return $statement->rowCount();
    })->unwrapOr(0);
    
    print_r($cnt);
    
    Native
    $query = $pdo->query("select id,name from link");
    $result = [];
    
    if ($query) {
        $res = $query->fetchAll();
        if ($res) {
            foreach ($res as $key => $item) {
                $result[] = [
                    "link_id" => $item["id"],
                    "link_name" => $item["name"] ?? "匿名链接",
                ];
            }
        }
    }
    
    Option
    $result = Some($pdo->query("select id,name from link"))->andThen(function ($state) {
        return $state->fetchAll();
    })->filter(function ($item) {
        return [
            "link_id" => $item["id"],
            "link_name" => Some($item["name"])->unwrapOr("匿名链接"),
        ];
    })->unwrapOr([]);
    
    print_r($result);
    
    1 条回复    2018-09-12 18:25:21 +08:00
    AngelCriss
        1
    AngelCriss  
       2018-09-12 18:25:21 +08:00 via Android
    啥叫函数式?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1049 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 19:34 · PVG 03:34 · LAX 11:34 · JFK 14:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.