」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 人類可以閱讀代碼的重要性

人類可以閱讀代碼的重要性

發佈於2025-02-21
瀏覽:305

The Importance of Writing Code That Humans Can Read

关键要点

  • 清晰性至上: 可读性强的代码提升了可维护性和协作性,编写易于理解和修改的代码至关重要。
  • 函数和文件管理: 使用函数封装可重用代码,并将大型文件拆分成更小、更易于管理的部分,简化导航和理解。
  • 命名约定: 为函数和变量选择清晰且具有描述性的名称,以提高可读性并减少对额外注释的需求。
  • 避免过度优化: 虽然简洁且优化的代码很有吸引力,但在性能影响不显著的情况下,应优先考虑可读性,因为现代 JavaScript 引擎在代码优化方面非常高效。
  • 谨慎注释: 使用注释解释“为什么”这样做,而不是“做什么”,并保持注释的相关性和最新性,以帮助理解非明显的代码逻辑。

本文由 Matt Burnett、Simon Codrington 和 Nilson Jacques 共同评审。感谢所有 SitePoint 的同行评审者,使 SitePoint 内容达到最佳状态!

您是否曾经在一次运行中完成一个项目,而无需再次查看代码?我也没有。在处理旧项目时,您可能希望花费很少或根本不花时间来弄清楚代码的工作原理。可读性强的代码对于保持产品的可维护性以及让您和您的同事或合作者满意至关重要。

在 JS1k 竞赛中可以找到难以阅读代码的夸张示例,其目标是以 1024 个字符或更少的字符编写最佳 JavaScript 应用程序,以及 JSF*ck(顺便说一下,NSFW),这是一种深奥的编程风格,仅使用六个不同的字符来编写 JavaScript 代码。查看这些网站上的代码会让您想知道发生了什么。想象一下编写这样的代码并在几个月后尝试修复错误。

如果您定期浏览互联网或构建界面,您可能会知道,退出大型、笨重的表单比退出看起来简单而小的表单更容易。代码也是如此。当被认为更容易阅读和使用时,人们可能会更喜欢使用它。至少它会避免您因沮丧而扔掉电脑。

在本文中,我将探讨使代码更易于阅读的技巧和窍门,以及要避免的陷阱。

代码分割

坚持表单类比,表单有时会分成几部分,使其看起来不那么困难。代码也可以这样做。通过将其分成几部分,读者可以跳到与他们相关的部分,而不是费力地浏览丛林。

跨文件

多年来,我们一直在为网络优化各种事物。JavaScript 文件也不例外。想想缩小和预 HTTP/2,我们通过将脚本组合成一个来节省 HTTP 请求。今天,我们可以按照自己的意愿工作,并使用像 Gulp 或 Grunt 这样的任务运行器来处理我们的文件。可以肯定地说,我们可以按照自己喜欢的方式进行编程,并将优化(例如连接)留给工具。

// 从 API 加载用户数据
var getUsersRequest = new XMLHttpRequest();
getUsersRequest.open('GET', '/api/users', true);
getUsersRequest.addEventListener('load', function() {
    // 对用户执行某些操作
});

getUsersRequest.send();

//---------------------------------------------------
// 不同的功能从这里开始。也许
// 这是一个分成文件的时机。
//---------------------------------------------------

// 从 API 加载帖子数据
var getPostsRequest = new XMLHttpRequest();
getPostsRequest.open('GET', '/api/posts', true);
getPostsRequest.addEventListener('load', function() {
    // 对帖子执行某些操作
});

getPostsRequest.send();

函数

函数允许我们创建可以重用的代码块。通常,函数的内容是缩进的,因此很容易看到函数的起始位置和结束位置。一个好习惯是保持函数很小——10 行或更少。当函数命名正确时,也很容易理解调用函数时发生了什么。稍后我们将介绍命名约定。

// 从 API 加载用户数据
function getUsers(callback) {
    var getUsersRequest = new XMLHttpRequest();
    getUsersRequest.open('GET', '/api/users', true);
    getUsersRequest.addEventListener('load', function() {
        callback(JSON.parse(getUsersRequest.responseText));
    });

    getUsersRequest.send();
}

// 从 API 加载帖子数据
function getPosts(callback) {
    var getPostsRequest = new XMLHttpRequest();
    getPostsRequest.open('GET', '/api/posts', true);
    getPostsRequest.addEventListener('load', function() {
        callback(JSON.parse(getPostsRequest.responseText));
    });

    getPostsRequest.send();
}

// 由于命名正确,因此无需阅读实际函数即可轻松理解此代码
// getUsers(function(users) {
//     // 对用户执行某些操作
// });
// getPosts(function(posts) {
//     // 对帖子执行某些操作
// });

我们可以简化上面的代码。注意这两个函数几乎完全相同吗?我们可以应用“不要重复自己”(DRY)原则。这可以防止混乱。

function fetchJson(url, callback) {
    var request = new XMLHttpRequest();
    request.open('GET', url, true);
    request.addEventListener('load', function() {
        callback(JSON.parse(request.responseText));
    });

    request.send();
}

// 下面的代码仍然很容易理解
// 无需阅读上面的函数
fetchJson('/api/users', function(users) {
    // 对用户执行某些操作
});
fetchJson('/api/posts', function(posts) {
    // 对帖子执行某些操作
});

如果我们想通过 POST 请求创建一个新用户怎么办?此时,一种选择是向函数添加可选参数,从而向函数引入新的逻辑,使其过于复杂而无法成为一个函数。另一种选择是专门为 POST 请求创建一个新函数,这将导致代码重复。

我们可以通过面向对象编程获得两者的优点,允许我们创建一个可配置的单次使用对象,同时保持其可维护性。

注意:如果您需要专门关于面向对象 JavaScript 的入门知识,我推荐这段视频:面向对象 JavaScript 的权威指南

面向对象编程

考虑对象,通常称为类,它们是一组上下文感知的函数。一个对象非常适合放在专用文件中。在我们的例子中,我们可以为 XMLHttpRequest 构建一个基本的包装器。

HttpRequest.js

function HttpRequest(url) {
    this.request = new XMLHttpRequest();

    this.body = undefined;
    this.method = HttpRequest.METHOD_GET;
    this.url = url;

    this.responseParser = undefined;
}

HttpRequest.METHOD_GET = 'GET';
HttpRequest.METHOD_POST = 'POST';

HttpRequest.prototype.setMethod = function(method) {
    this.method = method;
    return this;
};

HttpRequest.prototype.setBody = function(body) {
    if (typeof body === 'object') {
        body = JSON.stringify(body);
    }

    this.body = body;
    return this;
};

HttpRequest.prototype.setResponseParser = function(responseParser) {
    if (typeof responseParser !== 'function') return;

    this.responseParser = responseParser;
    return this;
};

HttpRequest.prototype.send = function(callback) {
    this.request.addEventListener('load', function() {
        if (this.responseParser) {
            callback(this.responseParser(this.request.responseText));
        } else {
            callback(this.request.responseText);
        }
    }, false);

    this.request.open(this.method, this.url, true);
    this.request.send(this.body);
    return this;
};

app.js

new HttpRequest('/users')
    .setResponseParser(JSON.parse)
    .send(function(users) {
        // 对用户执行某些操作
    });

new HttpRequest('/posts')
    .setResponseParser(JSON.parse)
    .send(function(posts) {
        // 对帖子执行某些操作
    });

// 创建一个新用户
new HttpRequest('/user')
    .setMethod(HttpRequest.METHOD_POST)
    .setBody({
        name: 'Tim',
        email: '[email protected]'
    })
    .setResponseParser(JSON.parse)
    .send(function(user) {
        // 对新用户执行某些操作
    });

上面创建的 HttpRequest 类现在非常可配置,因此可以应用于我们的许多 API 调用。尽管实现(一系列链式方法调用)更复杂,但类的功能易于维护。在实现和可重用性之间取得平衡可能很困难,并且是特定于项目的。

使用 OOP 时,设计模式是一个很好的补充。虽然它们本身不会提高可读性,但一致性会!

人工语法

文件、函数、对象,这些只是粗略的线条。它们使您的代码易于扫描。使代码易于阅读是一种更为细致的艺术。最细微的细节都会产生重大影响。例如,将您的行长限制为 80 个字符是一个简单的解决方案,通常通过垂直线由编辑器强制执行。但还有更多!

命名

适当的命名可以导致即时识别,从而无需查找值是什么或函数的作用。

函数通常采用驼峰式命名法。以动词开头,然后是主语通常会有所帮助。

function getApiUrl() { /* ... */ }
function setRequestMethod() { /* ... */ }
function findItemsById(n) { /* ... */ }
function hideSearchForm() { /* ... */ }

对于变量名,尝试应用倒金字塔方法。主题放在前面,属性放在后面。

var element = document.getElementById('body'),
    elementChildren = element.children,
    elementChildrenCount = elementChildren.length;

// 定义一组颜色时,我在变量前加“color”前缀
var colorBackground = 0xFAFAFA,
    colorPrimary = 0x663399;

// 定义一组背景属性时,我使用 background 作为基准
var backgroundColor = 0xFAFAFA,
    backgroundImages = ['foo.png', 'bar.png'];

// 上下文可以改变一切
var headerBackgroundColor = 0xFAFAFA,
    headerTextColor = 0x663399;

能够区分普通变量和特殊变量也很重要。例如,常量的名称通常以大写字母编写,并带有下划线。

var URI_ROOT = window.location.href;

类通常采用驼峰式命名法,以大写字母开头。

function FooObject {
    // ...
}

一个小细节是缩写。有些人选择将缩写全部大写,而另一些人则选择坚持使用驼峰式命名法。使用前者可能会使识别后续缩写变得更加困难。

简洁性和优化

在许多代码库中,您可能会遇到一些“特殊”代码来减少字符数或提高算法的性能。

单行代码是简洁代码的一个示例。不幸的是,它们通常依赖于技巧或晦涩的语法。下面看到的嵌套三元运算符就是一个常见的例子。尽管它很简洁,但与普通的 if 语句相比,理解它的作用也可能需要一秒或两秒钟。小心使用语法快捷方式。

// 太棒了,有人设法把它做成了一行代码!
var state = isHidden ? 'hidden' : isAnimating ? 'animating' : '';

// 太棒了,有人设法让它易于阅读!
var state = '';
if (isAnimating) state = 'animating';
if (isHidden) state = 'hidden';

微优化是性能优化,通常影响很小。大多数情况下,它们不如性能较低的等效项易于阅读。

// 这可能是性能最高的
$el[0].checked;

// 但这些仍然很快,而且更容易阅读
// 来源:http://jsperf.com/prop-vs-ischecked/5
$el.prop('checked');
$el.is(':checked');
$el.attr('checked');

JavaScript 编译器非常擅长为我们优化代码,而且它们还在不断改进。除非未优化代码和优化代码之间的差异很明显(通常在数千或数百万次操作之后),否则建议选择更容易阅读的代码。

非代码

这具有讽刺意味,但保持代码可读性的更好方法是添加不会执行的语法。让我们称之为非代码。

空格

我很确定每个开发人员都曾有过其他开发人员提供,或者检查过某个网站的压缩代码——其中大多数空格都被删除的代码。第一次遇到这种情况可能会令人相当惊讶。在不同的视觉艺术领域,如设计和排版,空白与填充一样重要。您需要找到两者之间的微妙平衡。对这种平衡的看法因公司、团队和开发人员而异。幸运的是,有一些普遍认同的规则:

  • 每行一个表达式,
  • 缩进块的内容,
  • 可以使用额外的换行符来分隔代码部分。

任何其他规则都应与您合作的任何人讨论。无论您同意哪种代码风格,一致性都是关键。

function sendPostRequest(url, data, cb) {
    // 将一些赋值组合在一起并整齐地缩进
    var requestMethod = 'POST',
        requestHeaders = {
            'Content-Type': 'text/plain'
        };

    // XMLHttpRequest 初始化、配置和提交
    var request = new XMLHttpRequest();
    request.addEventListener('load', cb, false);
    request.open(requestMethod, url, false);
    request.send(data);
}

注释

与空格一样,注释可以成为为代码提供一些空间的好方法,还可以让您向代码添加详细信息。请务必添加注释以显示:

  • 非明显代码的解释和论证,
  • 修复解决的错误或异常以及可用的来源。
// 对图形的范围求和
var sum = values.reduce(function(previousValue, currentValue) { 
    return previousValue   currentValue;
});

并非所有修复都是显而易见的。添加其他信息可以阐明很多内容:

if ('addEventListener' in element) {
    element.addEventListener('click', myFunc);
}
// IE8 及更低版本不支持 .addEventListener,
// 因此应改用 .attachEvent
// http://caniuse.com/#search=addEventListener
// https://msdn.microsoft.com/en-us/library/ms536343(VS.85).aspx
else {
    element.attachEvent('click', myFunc);
}

内联文档

编写面向对象软件时,内联文档与普通注释一样,可以为代码提供一些呼吸空间。它们还有助于阐明属性或方法的目的和细节。许多 IDE 将它们用于提示,生成的文档工具也使用它们!无论原因是什么,编写文档都是一项极好的实践。

/**
 * 创建 HTTP 请求
 * @constructor
 * @param {string} url
 */
function HttpRequest(url) {
    // ...
}

/**
 * 设置标头对象
 * @param {Object} headers
 * @return {HttpRequest}
 */
HttpRequest.prototype.setHeaders = function(headers) {
    for (var header in headers) {
        this.headers[header] = headers[header];
    }

    // 返回自身以进行链式调用
    return this;
};

回调难题

事件和异步调用是 JavaScript 的强大功能,但它通常会使代码更难以阅读。

异步调用通常使用回调提供。有时,您希望按顺序运行它们,或者等待所有异步调用准备好。

function doRequest(url, success, error) { /* ... */ }

doRequest('https://example.com/api/users', function(users) {
    doRequest('https://example.com/api/posts', function(posts) {
        // 对用户和帖子执行某些操作
    }, function(error) {
        // /api/posts 出错了
    });
}, function(error) {
    // /api/users 出错了
});

Promise 对象在 ES2015(也称为 ES6)中引入,用于解决这两个问题。它允许您展平嵌套的异步请求。

function doRequest(url) {
    return new Promise(function(resolve, reject) {
        // 初始化请求
        // 成功时调用 resolve(response)
        // 错误时调用 reject(error)
    });
}

// 首先请求用户
doRequest('https://example.com/api/users')
// .then() 在所有异步调用都成功执行时执行
.then(function(users) { /* ... */ })
// .catch() 在任何 promise 触发 reject() 函数时执行
.catch(function(error) { /* ... */ });

// 并行运行多个 promise
Promise.all([
    doRequest('https://example.com/api/users'),
    doRequest('https://example.com/api/posts')
])
.then(function(responses) { /* ... */ })
.catch(function(error) { /* ... */ });

尽管我们引入了其他代码,但这更容易正确解释。您可以在此处阅读更多关于 Promise 的信息:JavaScript 变得异步(而且很棒)

ES6/ES2015

如果您了解 ES2015 规范,您可能已经注意到本文中的所有代码示例都是旧版本的(Promise 对象除外)。尽管 ES6 为我们提供了强大的功能,但在可读性方面还是有一些问题。

胖箭头语法定义了一个函数,该函数从其父作用域继承 this 的值。至少,这就是它被设计的原因。使用它来定义常规函数也很诱人。

var add = (a, b) => a   b;
console.log(add(1, 2)); // 3

另一个示例是 rest 和 spread 语法。

/**
 * 对数字列表求和
 * @param {Array} numbers
 * @return {Number}
 */
function add(...numbers) {
    return n.reduce(function(previousValue, currentValue) {
        return previousValue   currentValue;
    }, 0);
}

add(...[1, 2, 3]);

/**
 * 对 a、b 和 c 求和
 * @param {Number} a
 * @param {Number} b
 * @param {Number} c
 * @return {Number}
 */
function add(a, b, c) {
    return a   b   c;
}

add(1, 2, 3);

我的意思是,ES2015 规范引入许多有用但晦涩、有时令人困惑的语法,这使得它容易被滥用于单行代码。我不希望阻止使用这些功能。我希望鼓励谨慎使用它们。

结论

在项目的每个阶段,都要记住保持代码的可读性和可维护性。从文件系统到微小的语法选择,一切都很重要。尤其是在团队中,很难始终强制执行所有规则。代码审查可以提供帮助,但仍然存在人为错误的余地。幸运的是,有一些工具可以帮助您做到这一点!

  • JSHint – 一个 JavaScript 语言检查器,用于保持代码无错误
  • Idiomatic – 一种流行的代码风格标准,但您可以随意偏离
  • EditorConfig – 定义跨编辑器的代码风格

除了代码质量和样式工具之外,还有一些工具可以使任何代码更易于阅读。尝试不同的语法高亮主题,或尝试使用小地图来查看脚本的自上而下的概述(Atom、Brackets)。

您对编写可读且可维护的代码有何看法?我很想在下面的评论中听到您的想法。

关于可读代码的常见问题解答

为什么代码对人类来说必须易于阅读?

代码的可读性至关重要,原因如下。首先,它使代码更容易理解、调试和维护。当代码可读时,其他开发人员更容易理解代码的作用,这在协作环境中尤其重要。其次,可读性强的代码更有可能正确。如果开发人员可以轻松理解代码,那么他们在修改代码时不太可能引入错误。最后,可读性强的代码更容易测试。如果代码清晰简洁,则更容易确定需要测试的内容以及如何测试。

什么使编程语言易于阅读?

如果编程语言具有清晰简洁的语法、使用有意义的标识符以及包含解释代码作用的注释,则该语言被认为易于阅读。像 Python 和 Ruby 这样的高级语言通常被认为易于阅读,因为它们使用类似英语的语法并允许使用清晰的、描述性的变量名。但是,也可以通过良好的编码实践(例如一致的缩进、使用空格和全面的注释)来提高像 C 或 Java 这样的低级语言的可读性。

函数如何减少代码量?

函数可以通过允许开发人员重用代码来显著减少代码量。与其多次编写相同的代码,不如编写一次函数,然后在需要执行特定任务时调用该函数。这不仅使代码更短、更易于阅读,而且还使代码更容易维护和调试,因为任何更改只需要在一个地方进行。

机器代码和高级语言有什么区别?

机器代码是最低级的编程语言,由可以直接由计算机中央处理器 (CPU) 执行的二进制代码组成。另一方面,高级语言更接近人类语言,需要在执行之前由编译器或解释器将其转换为机器代码。高级语言通常更容易阅读和编写,并且它们提供了更多与硬件的抽象,使它们更易于在不同类型的机器之间移植。

解释器和编译器是如何工作的?

解释器和编译器是将高级语言转换为机器代码的工具。解释器逐行翻译和执行代码,这允许交互式编码和调试。但是,这可能比编译代码慢。另一方面,编译器会在执行之前将整个程序转换为机器代码,这可以提高执行速度。但是,任何代码错误都只有在编译整个程序后才能发现。

什么是汇编语言?

汇编语言是一种低级编程语言,它使用助记符代码来表示机器代码指令。每种汇编语言都特定于特定的计算机体系结构。虽然它比机器代码更易于阅读,但它仍然比高级语言更难阅读和编写。但是,它允许直接控制硬件,这在某些情况下非常有用。

如何提高代码的可读性?

有几种方法可以提高代码的可读性。这些方法包括使用有意义的变量和函数名、一致地缩进代码、使用空格分隔代码的不同部分以及包含解释代码作用的注释。遵循您使用的编程语言的约定和最佳实践也很重要。

注释在使代码可读方面起什么作用?

注释在使代码可读方面起着至关重要的作用。它们提供了对代码作用、做出某些决策的原因以及复杂代码部分如何工作的解释。这对于需要理解和使用您的代码的其他开发人员来说可能非常有帮助。但是,重要的是要使注释简洁且相关,并在代码更改时更新它们。

可读性强的代码如何影响协作?

可读性强的代码极大地促进了协作。当代码易于阅读时,其他开发人员更容易理解和参与贡献。这在大型项目中尤其重要,在大型项目中,多个开发人员正在处理代码库的不同部分。可读性强的代码还可以更容易地让新的团队成员加入,因为他们可以快速了解代码的作用以及它的工作原理。

可读性强的代码如何影响软件质量?

可读性强的代码可以显著提高软件质量。当代码易于阅读时,更容易发现和修复错误,并确保代码正在执行其应执行的操作。它还可以使随着时间的推移更容易维护和增强软件,因为它清楚地说明了代码的每一部分的作用。这可以导致更可靠、更高效和更强大的软件。

最新教學 更多>
  • 如何在鼠標單擊時編程選擇DIV中的所有文本?
    如何在鼠標單擊時編程選擇DIV中的所有文本?
    在鼠標上選擇div文本單擊帶有文本內容,用戶如何使用單個鼠標單擊單擊div中的整個文本?這允許用戶輕鬆拖放所選的文本或直接複製它。 在單個鼠標上單擊的div元素中選擇文本,您可以使用以下Javascript函數: function selecttext(canduterid){ if(d...
    程式設計 發佈於2025-04-06
  • 我可以將加密從McRypt遷移到OpenSSL,並使用OpenSSL遷移MCRYPT加密數據?
    我可以將加密從McRypt遷移到OpenSSL,並使用OpenSSL遷移MCRYPT加密數據?
    將我的加密庫從mcrypt升級到openssl 問題:是否可以將我的加密庫從McRypt升級到OpenSSL?如果是這樣,如何? 答案:是的,可以將您的Encryption庫從McRypt升級到OpenSSL。 可以使用openssl。 附加說明: [openssl_decrypt()函數要求...
    程式設計 發佈於2025-04-06
  • 如何將PANDAS DataFrame列轉換為DateTime格式並按日期過濾?
    如何將PANDAS DataFrame列轉換為DateTime格式並按日期過濾?
    將pandas dataframe列轉換為dateTime格式示例:使用column(mycol)包含以下格式的以下dataframe,以自定義格式:})指定的格式參數匹配給定的字符串格式。轉換後,MyCol列現在將包含DateTime對象。 date date filtering > = ...
    程式設計 發佈於2025-04-06
  • 為什麼不使用CSS`content'屬性顯示圖像?
    為什麼不使用CSS`content'屬性顯示圖像?
    在Firefox extemers屬性為某些圖像很大,&& && && &&華倍華倍[華氏華倍華氏度]很少見,卻是某些瀏覽屬性很少,尤其是特定於Firefox的某些瀏覽器未能在使用內容屬性引用時未能顯示圖像的情況。這可以在提供的CSS類中看到:。 googlepic { 內容:url(&...
    程式設計 發佈於2025-04-06
  • 如何正確使用與PDO參數的查詢一樣?
    如何正確使用與PDO參數的查詢一樣?
    在pdo 中使用類似QUERIES在PDO中的Queries時,您可能會遇到類似疑問中描述的問題:此查詢也可能不會返回結果,即使$ var1和$ var2包含有效的搜索詞。錯誤在於不正確包含%符號。 通過將變量包含在$ params數組中的%符號中,您確保將%字符正確替換到查詢中。沒有此修改,PD...
    程式設計 發佈於2025-04-06
  • 在程序退出之前,我需要在C ++中明確刪除堆的堆分配嗎?
    在程序退出之前,我需要在C ++中明確刪除堆的堆分配嗎?
    在C中的顯式刪除 在C中的動態內存分配時,開發人員通常會想知道是否有必要在heap-procal extrable exit exit上進行手動調用“ delete”操作員,但開發人員通常會想知道是否需要手動調用“ delete”操作員。本文深入研究了這個主題。 在C主函數中,使用了動態分配變量(...
    程式設計 發佈於2025-04-06
  • 如何在其容器中為DIV創建平滑的左右CSS動畫?
    如何在其容器中為DIV創建平滑的左右CSS動畫?
    通用CSS動畫,用於左右運動 ,我們將探索創建一個通用的CSS動畫,以向左和右移動DIV,從而到達其容器的邊緣。該動畫可以應用於具有絕對定位的任何div,無論其未知長度如何。 問題:使用左直接導致瞬時消失 更加流暢的解決方案:混合轉換和左 [並實現平穩的,線性的運動,我們介紹了線性的轉換。...
    程式設計 發佈於2025-04-06
  • 為什麼我會收到MySQL錯誤#1089:錯誤的前綴密鑰?
    為什麼我會收到MySQL錯誤#1089:錯誤的前綴密鑰?
    mySQL錯誤#1089:錯誤的前綴鍵錯誤descript [#1089-不正確的前綴鍵在嘗試在表中創建一個prefix鍵時會出現。前綴鍵旨在索引字符串列的特定前綴長度長度,以便更快地搜索這些前綴。 理解prefix keys `這將在整個Movie_ID列上創建標準主鍵。主密鑰對於唯一識...
    程式設計 發佈於2025-04-06
  • 如何從PHP中的Unicode字符串中有效地產生對URL友好的sl。
    如何從PHP中的Unicode字符串中有效地產生對URL友好的sl。
    為有效的slug生成首先,該函數用指定的分隔符替換所有非字母或數字字符。此步驟可確保slug遵守URL慣例。隨後,它採用ICONV函數將文本簡化為us-ascii兼容格式,從而允許更廣泛的字符集合兼容性。 接下來,該函數使用正則表達式刪除了不需要的字符,例如特殊字符和空格。此步驟可確保slug僅包...
    程式設計 發佈於2025-04-06
  • 如何使用不同數量列的聯合數據庫表?
    如何使用不同數量列的聯合數據庫表?
    合併列數不同的表 當嘗試合併列數不同的數據庫表時,可能會遇到挑戰。一種直接的方法是在列數較少的表中,為缺失的列追加空值。 例如,考慮兩個表,表 A 和表 B,其中表 A 的列數多於表 B。為了合併這些表,同時處理表 B 中缺失的列,請按照以下步驟操作: 確定表 B 中缺失的列,並將它們添加到表的...
    程式設計 發佈於2025-04-06
  • 如何限制動態大小的父元素中元素的滾動範圍?
    如何限制動態大小的父元素中元素的滾動範圍?
    在交互式接口中實現垂直滾動元素的CSS高度限制問題: 考慮一個佈局,其中我們具有可滾動的映射div,該圖像div與用戶的垂直滾動一起移動,同時維持固定的固定sidebar。但是,地圖的滾動無限期擴展,超過了視口的高度,阻止用戶訪問頁面頁腳。 映射{} 因此。我們不使用jQuery的“ .ai...
    程式設計 發佈於2025-04-06
  • 如何檢查對像是否具有Python中的特定屬性?
    如何檢查對像是否具有Python中的特定屬性?
    方法來確定對象屬性存在尋求一種方法來驗證對像中特定屬性的存在。考慮以下示例,其中嘗試訪問不確定屬性會引起錯誤: >>> a = someClass() >>> A.property Trackback(最近的最新電話): 文件“ ”,第1行, attributeError:SomeClass實...
    程式設計 發佈於2025-04-06
  • 在Ubuntu/linux上安裝mysql-python時,如何修復\“ mysql_config \”錯誤?
    在Ubuntu/linux上安裝mysql-python時,如何修復\“ mysql_config \”錯誤?
    mysql-python安裝錯誤:“ mysql_config找不到”“ 由於缺少MySQL開發庫而出現此錯誤。解決此問題,建議在Ubuntu上使用該分發的存儲庫。使用以下命令安裝Python-MysqldB: sudo apt-get安裝python-mysqldb sudo pip in...
    程式設計 發佈於2025-04-06
  • 版本5.6.5之前,使用current_timestamp與時間戳列的current_timestamp與時間戳列有什麼限制?
    版本5.6.5之前,使用current_timestamp與時間戳列的current_timestamp與時間戳列有什麼限制?
    在時間戳列上使用current_timestamp或MySQL版本中的current_timestamp或在5.6.5 此限制源於遺留實現的關注,這些限制需要對當前的_timestamp功能進行特定的實現。 創建表`foo`( `Productid` int(10)unsigned not ...
    程式設計 發佈於2025-04-06

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3