PHP技巧和窍门来简化你的代码

2021-08-23 17:36:05 浏览数 (1)

PHP技巧和窍门来简化你的代码

    • 技巧1 : (if and else)
    • 技巧2 : (if blocks: less vs more)
    • 技巧3 : (验证多个字符串)
    • 技巧4: (??)
    • 技巧5 :(递归优先于重复)
    • 技巧6 : (PHP HTML)
    • 技巧7: (编写功能块)
    • 技巧8: (使用类型)
    • 技巧9 : (框架/库是没有坏处的)
    • 提示10 : (不要只是为了写代码!)
    • 谢谢阅读
    • 相关内容

对我而言,使用PHP一直是我最有趣的经历,无论是从事大型项目还是小型项目,并在每次旅行中都学到一些新东西。

我将分享一些小技巧,这些技巧可以帮助大家减少几行代码。如果您有任何想法,欢迎评论提问或者加我建的群进行讨论

技巧1 : (if and else)

您可能以前在教程或其他文章中已经看到过这一点,但这是我真正要提到的非常重要的一点点内容。 实际上,在代码中使用elseelse if块是没错的,但是,在某些情况下,这些块变得多余。 让我们看一个例子:

代码语言:javascript复制
function output_gender(bool $user_is_male) {
    if ($user_is_male) {
        return "User is male";
    } else {
        return "User is female";
    }
}

在这种情况下,output_gender函数基于 user_is_male返回的设置输出为true或false。 当在函数中使用return时,return语句下面的任何代码都将被完全忽略,因此,如果 user_is_male为true,则else块将被忽略,因为返回了值。 有了这个概念,我们可以像这样摆脱else块:

代码语言:javascript复制
function output_gender(bool $user_is_male) {
    if ($user_is_male) {
        return "User is male";
    }

    return "User is female";
}

我们知道,如果传入的条件为false,则if语句将不会运行。 这意味着它将直接跳到"User is female"部分。

技巧2 : (if blocks: less vs more)

技巧2建立在我们上面刚刚看过的技巧上,但更深入了。 在if/else甚至使用技巧1的示例中,您可能会遇到以下情况:一个块(不管为if或else)的代码少于另一个块。 在这种情况下,最好先用较少的代码处理该块。 让我们看一个真实的例子。

代码语言:javascript复制
public function categoryWithPosts($category)
{
    $category = Category::find($category);

    if ($category) {
        $category->posts = $category->posts()->published()->get();
        return response(['data' => $category], 200);
    } else {
        return response(['error' => 'Category not found'], 404);
    }
}

上面的这段代码检查职位类别,并根据是否找到该类别来运行条件。 如果只用技巧1,我们将得到如下代码:

代码语言:javascript复制
public function categoryWithPosts($category)
{
    $category = Category::find($category);

    if ($category) {
        $category->posts = $category->posts()->published()->get();
        // having any more code here would
        // bloat this part of the function
        return response(['data' => $category], 200);
    }

    return response(['error' => 'Category not found'], 404);
}

这段代码是正确的,但是,您可以清楚地看到我们的主要代码用{}包裹起来,并被进一步推入。 如果这段代码明显更长,那么将其全部保留在if块中将是一件痛苦的事情。 在技巧2之后,我们可以改用以下方法:

代码语言:javascript复制
public function categoryWithPosts($category)
{
    $category = Category::find($category);

    if (!$category) {
        return response(['error' => 'Category not found'], 404);
    }

    $category->posts = $category->posts()->published()->get();
    // we can freely have more code here
    // without worrying about the code looking weird
    return response(['data' => $category], 200);
}

由于else块的代码较少,因此我们使用带有!的否定语句。 使该代码先运行。因此,我们的if就算包含if not category, 也可以运行代码。…这为我们提供了更多空间来自由处理我们的主要代码。

技巧3 : (验证多个字符串)

假设我们要查找某个变量是否为多个字符串之一,显然我们必须编写一堆条件语句来验证这一点:

代码语言:javascript复制
$item = "candy";

switch ($item) {
    case 'candy':
        return true;
    case 'toy':
        return true;
    default:
        return false;
}
// we're not adding break because we're using return

// or
if ($item == 'candy' || $item == 'toy') {
    return true;
}

return false;

如果item变量既不是candy也不是toy,则此代码返回false。 这是完全正确的,但是,这是非常冗余的。 其实我们可以检查数组以查找要查找的字符串:

代码语言:javascript复制
if (in_array($item, ["candy", "toy"])) {
    return true;
}

return false;

就算这样,你还可以进一步缩短,因为in_array返回一个布尔值。

代码语言:javascript复制
return in_array($item, ["candy", "toy"]);

我们将这些行缩短为仅一行,简洁吗?这是怎么做到的的?我们有一个包含要检查的字符串的数组。然后我们将其传递给in_array。这将创建一个简单的条件,例如:

代码语言:javascript复制
if $item is inside the array holding "candy" and "toy", return true, else false

您可能想知道,为什么不直接返回$ item是candy还是toy,因为那也只是一行,就像这样:

代码语言:javascript复制
return ($item == 'candy' || $item == 'toy');

这将给我们相同的结果,但是假设我们正在检查10个字符串:

代码语言:javascript复制
return ($letter == 'a' || $letter == 'b' || $letter == 'c' || $letter == 'd' ...);

与以下内容相比,您可以清楚地看到这很容易失控:

代码语言:javascript复制
return in_array($letter, ["a", "b", "c", "d", ...]);

请注意,第一个参数in_array是我们实际上正在检查的字符串

技巧4: (??)

??这是创建没有两个部分的内联条件的最简单方法。我什么意思 让我们看一个示例,该示例将为我做所有解释。

代码语言:javascript复制
$data = [
    "a" => 1,
    "b" => 2,
    "c" => null,
];

return $data["c"] ? $data["c"] : "No data";

此处的最后一行检查键入c的内容$data是否为真,否则返回“No data”。

我们可以用??重写最后一行 看起来像这样:

代码语言:javascript复制
// ...
return $data["c"] ?? "No data";

在这种情况下??行为类似于其他语言中的||逻辑运算符。一个真实的例子如下:

代码语言:javascript复制
$user = getUserFromDb($user_id) ?? trigger_error("User id is invalid");

echo $user;

getUserFromDb用于从某个地方的数据库返回用户,但是,如果找不到该用户,则不设置用户变量,而是使用trigger_error破坏应用程序。没有??我们必须改写成这样:

代码语言:javascript复制
$user = getUserFromDb($user_id);

if (!$user) {
    trigger_error("User id is invalid");
}

echo $user;

技巧5 :(递归优先于重复)

我认为此技巧非常简单,请尝试使用递归性,而不要重复很多次。在某些情况下会让您重复一些代码,这很好,但是如果您发现要重复相同的代码,只需将其设为方法即可。递归从何而来?让我们看一个例子:这是我为Leaf框架的request对象编写的一种方法,用于返回传递到请求中的特定字段。

代码语言:javascript复制
/**
 * Returns request data
 *
 * This methods returns data passed into the request (request or form data).
 * This method returns get, post, put patch, delete or raw faw form data or NULL
 * if the data isn't found.
 *
 * @param string|array $params The parameter(s) to return
 * @param bool $safeData Sanitize output
 */

这意味着该方法可以接受数组或字符串,并且根据输入,它将返回字符串或数组。解决方案是检查输入是否为数组,在其上循环以获取数组中的字符串,然后对这些字符串执行数据获取,如下所示。

代码语言:javascript复制
public function get($params, bool $safeData = true)
{
    if (is_string($params)) return $this->body($safeData)[$params] ?? null;

    $data = [];
    foreach ($params as $param) {
        $data[$param] = $this->body($safeData)[$params] ?? null;
    }
    return $data;
}

在这里,您会注意到this->body(

代码语言:javascript复制
public function get($params, bool $safeData = true)
{
    if (is_string($params)) return $this->body($safeData)[$params] ?? null;

    $data = [];
    foreach ($params as $param) {
        $data[$param] = $this->get($param, $safeData); // I called the function again
    }
    return $data;
}

这样可以确保在循环值是一个字符串之前,它不会尝试获取其数据。与上述相比,这是一个小技巧,但绝对有用。请注意,此函数是类范围的,因此使用$this

技巧6 : (PHP HTML)

当您想用HTML中的PHP或PHP中的HTML编写时。 我们通常会做类似的事情:

代码语言:javascript复制
<?php
foreach ($items as $item) {
    echo '
        <div class="product__card">
            <h3>{$item->name}</h3>
        </div>
    ';
}
?>

尽管很好,您可以清楚地看到,我们将HTML输出为字符串。 HTML越庞大,匹配标签并准确跟踪我们正在编写的HTML的哪个部分就变得越有压力。 有一个整洁的解决方案。

代码语言:javascript复制
<?php foreach ($items as $item): ?>
    <div class="product__card">
        <h3><?php echo $item->name; ?></h3>
    </div>
<?php endforeach; ?>

您可以清楚地看到我们如何保持HTML格式和代码对齐……不,这不是模板引擎,这只是PHP使我们变得简单。 关于PHP的一件主要事情是它如何允许以许多不同的方式完成同一件事。 在上面的示例中,我们使用:

代码语言:javascript复制
foreach (...):
// code
endforeach;

// also works with if
if (...):
// code
endif;

// also
if (...) #one line code

while():
// ...
endwhile;

技巧7: (编写功能块)

功能块的范围可以从一个大功能到一个单独的包装器,围绕默认的PHP函数,重点只是创建该功能块。 这不仅是为了避免重复,而且还可以加快工作流程并提高代码的可读性。

您可以编写一个简单的方法来创建重定向,如下所示:

代码语言:javascript复制
function redirectTo($route) {
    header("location: $route", true, 302);
}

因此,与其每次都写header("location: /home", true, 302),不如编写redirectTo("/home")。 这同样适用于第三方库和较长的过程,它们以开放的方式编写可重用的代码块,例如:

代码语言:javascript复制
UserNotification::send($user_id, $notification);

显然比每次必须向用户发送通知时写一堆代码要好。另一个很小但非常有用的技巧。

技巧8: (使用类型)

另一个简单明了。这是PHP中使用最少的功能,但功能非常强大。此功能可以为您和其他开发人员减轻很多压力(如果您与团队合作)。

当然,您可以像上面技巧5中的示例一样编写函数说明,但是在大型项目中为所有函数和变量编写函数说明成为一项艰巨的任务。

让我们看看类型如何在以后拯救我们的生命:

代码语言:javascript复制
function getItem($item) {
    // $item is expected to be an array
    // for whatever reason
    return allItems()[$item[0]];
}

如果几个星期后,另一个开发人员甚至是您自己在项目上工作,请参见getItem方法,$item显然可以看到该变量是一个字符串,但是该函数是为处理数组而编写的。

这里的危险之处在于,传递字符串不会破坏应用程序,它仍然可以完美运行。为什么?

如果将“ chair”传递到函数中,它将被评估为allItems()["c"],最终将导致错误,使您在12am

0 人点赞