찾다

PHP安全编程

Jun 23, 2016 pm 02:30 PM
PHP 보안 프로그래밍

PHP 应用程序中的安全性包括远程安全性和本地安全性。本文将揭示 PHP 开发人员在实现具有这两种安全性的 Web 应用程序时应该养成的习惯。
在提及安全性问题时,需要注意,除了实际的平台和操作系统安全性问题之外,您还需要确保编写安全的应用程序。在编写 PHP 应用程序时,请应用下面的七个习惯以确保应用程序具有最好的安全性:

验证输入
保护文件系统
保护数据库
保护会话数据
保护跨站点脚本(Cross-site scripting,XSS)漏洞
检验表单 post
针对跨站点请求伪造(Cross-Site Request Forgeries,CSRF)进行保护

本部分设定了隐藏,您已回复过了,以下是隐藏的内容


验证输入

在 提及安全性问题时,验证数据是您可能采用的最重要的习惯。而在提及输入时,十分简单:不要相信用户。您的用户可能十分优秀,并且大多数用户可能完全按照期 望来使用应用程序。但是,只要提供了输入的机会,也就极有可能存在非常糟糕的输入。作为一名应用程序开发人员,您必须阻止应用程序接受错误的输入。仔细考 虑用户输入的位置及正确值将使您可以构建一个健壮、安全的应用程序。

虽然后文将介绍文件系统与数据库交互,但是下面列出了适用于各种验证的一般验证提示:

使用白名单中的值
始终重新验证有限的选项
使用内置转义函数
验证正确的数据类型(如数字)
白名单中的值(White-listed value)是正确的值,与无效的黑名单值(Black-listed value)相对。两者之间的区别是,通常在进行验证时,可能值的列表或范围小于无效值的列表或范围,其中许多值可能是未知值或意外值。

在进行验证时,记住设计并验证应用程序允许使用的值通常比防止所有未知值更容易。例如,要把字段值限定为所有数字,需要编写一个确保输入全都是数字的例程。不要编写用于搜索非数字值并在找到非数字值时标记为无效的例程。

保护文件系统

2000 年 7 月,一个 Web 站点泄露了保存在 Web 服务器的文件中的客户数据。该 Web 站点的一个访问者使用 URL 查看了包含数据的文件。虽然文件被放错了位置,但是这个例子强调了针对攻击者保护文件系统的重要性。

如果 PHP 应用程序对文件进行了任意处理并且含有用户可以输入的变量数据,请仔细检查用户输入以确保用户无法对文件系统执行任何不恰当的操作。清单 1 显示了下载具有指定名的图像的 PHP 站点示例。


清单 1. 下载文件
[php]                
if ($_POST['submit'] == 'Download') {
    $file = $_POST['fileName'];
    header("Content-Type: application/x-octet-stream");
    header("Content-Transfer-Encoding: binary");
    header("Content-Disposition: attachment; filename=\"" . $file . "\";" );
    $fh = fopen($file, 'r');
    while (! feof($fh))
    {
        echo(fread($fh, 1024));
    }
    fclose($fh);
} else {
    echo("

        echo("title>Guard your filesystem");
    echo("
        "\" method=\"post\">");
    echo("
    echo(isset($_REQUEST['fileName']) ? $_REQUEST['fileName'] : '');
    echo("\" />");
    echo("
");
    echo("");
}[/php]    



正 如您所见,清单 1 中比较危险的脚本将处理 Web 服务器拥有读取权限的所有文件,包括会话目录中的文件(请参阅 “保护会话数据”),甚至还包括一些系统文件(例如 /etc/passwd)。为了进行演示,这个示例使用了一个可供用户键入文件名的文本框,但是可以在查询字符串中轻松地提供文件名。

同时配置用户输入和文件系统访问权十分危险,因此最好把应用程序设计为使用数据库和隐藏生成的文件名来避免同时配置。但是,这样做并不总是有效。清单 2 提供了验证文件名的示例例程。它将使用正则表达式以确保文件名中仅使用有效字符,并且特别检查圆点字符:..。


清单 2. 检查有效的文件名字符
[php]                    
function isValidFileName($file) {
    /* don't allow .. and allow any "word" character \ / */
    return preg_match('/^(((?:\.)(?!\.))|\w)+$/', $file);
}[/php]    

保护数据库

2008 年 4 月,美国某个州的狱政局在查询字符串中使用了 SQL 列名,因此泄露了保密数据。这次泄露允许恶意用户选择需要显示的列、提交页面并获得数据。这次泄露显示了用户如何能够以应用程序开发人员无法预料的方法执 行输入,并表明了防御 SQL 注入攻击的必要性。

清单 3 显示了运行 SQL 语句的示例脚本。在本例中,SQL 语句是允许相同攻击的动态语句。此表单的所有者可能认为表单是安全的,因为他们已经把列名限定为选择列表。但是,代码疏忽了关于表单欺骗的最后一个习惯 ? 代码将选项限定为下拉框并不意味着其他人不能够发布含有所需内容的表单(包括星号 [*])。


清单 3. 执行 SQL 语句
[php]                


SQL Injection Example


    method="post">
    value="        $_POST['account_number'] : ''); ?>" />



if ($_POST['submit'] == 'Save') {
    /* do the form processing */
    $link = mysql_connect('hostname', 'user', 'password') or
        die ('Could not connect' . mysql_error());
    mysql_select_db('test', $link);
        
        $col = $_POST['col'];

    $select = "SELECT " . $col . " FROM account_data WHERE account_number = "
        . $_POST['account_number'] . ";" ;
    echo '

' . $select . '

';

    $result = mysql_query($select) or die('

' . mysql_error() . '

');

    echo '';
    while ($row = mysql_fetch_assoc($result)) {
        echo '';
        echo '';
        echo '';
    }
    echo '
' . $row[$col] . '
';

    mysql_close($link);
}
?>

[/php]



因此,要形成保护数据库的习惯,请尽可能避免使用动态 SQL 代码。如果无法避免动态 SQL 代码,请不要对列直接使用输入。清单 4 显示了除使用静态列外,还可以向帐户编号字段添加简单验证例程以确保输入值不是非数字值。


清单 4. 通过验证和 mysql_real_escape_string() 提供保护
[php]                


SQL Injection Example


    method="post">
    value="        $_POST['account_number'] : ''); ?>" />     value="Save" name="submit" />


function isValidAccountNumber($number)
{
    return is_numeric($number);
}

if ($_POST['submit'] == 'Save') {

    /* Remember habit #1--validate your data! */
    if (isset($_POST['account_number']) &&
    isValidAccountNumber($_POST['account_number'])) {

        /* do the form processing */
        $link = mysql_connect('hostname', 'user', 'password') or
        die ('Could not connect' . mysql_error());
        mysql_select_db('test', $link);

        $select = sprintf("SELECT account_number, name, address " .
        " FROM account_data WHERE account_number = %s;",
        mysql_real_escape_string($_POST['account_number']));
        echo '

' . $select . '

';

        $result = mysql_query($select) or die('

' . mysql_error() . '

');

        echo '';
        while ($row = mysql_fetch_assoc($result)) {
            echo '';
            echo '';
            echo '';
            echo '';
            echo '';
        }
        echo '
' . $row['account_number'] . '' . $row['name'] . '' . $row['address'] . '
';

        mysql_close($link);
    } else {
        echo "" .
    "Please supply a valid account number!
";

    }
}
?>

[/php]



本 例还展示了 mysql_real_escape_string() 函数的用法。此函数将正确地过滤您的输入,因此它不包括无效字符。如果您一直依赖于 magic_quotes_gpc,那么需要注意它已被弃用并且将在 PHP V6 中删除。从现在开始应避免使用它并在此情况下编写安全的 PHP 应用程序。此外,如果使用的是 ISP,则有可能您的 ISP 没有启用 magic_quotes_gpc。

最后,在改进的示例中,您 可以看到该 SQL 语句和输出没有包括动态列选项。使用这种方法,如果把列添加到稍后含有不同信息的表中,则可以输出这些列。如果要使用框架以与数据库结合使用,则您的框架 可能已经为您执行了 SQL 验证。确保查阅文档以保证框架的安全性;如果仍然不确定,请进行验证以确保稳妥。即使使用框架进行数据库交互,仍然需要执行其他验证。

保护会话

默认情况下,PHP 中的会话信息将被写入临时目录。考虑清单 5 中的表单,该表单将显示如何存储会话中的用户 ID 和帐户编号。


清单 5. 存储会话中的数据
[php]                
session_start();
?>


Storing session information


if ($_POST['submit'] == 'Save') {
    $_SESSION['userName'] = $_POST['userName'];
    $_SESSION['accountNumber'] = $_POST['accountNumber'];
}
?>
    method="post">

    value="" />


    value="    $_POST['accountNumber'] : ''); ?>" />





[/php]



清单 6 显示了 /tmp 目录的内容。


清单 6. /tmp 目录中的会话文件
                
-rw-------  1 _www    wheel       97 Aug 18 20:00 sess_9e4233f2cd7cae35866cd8b61d9fa42b



正如您所见,在输出时(参见清单 7),会话文件以非常易读的格式包含信息。由于该文件必须可由 Web 服务器用户读写,因此会话文件可能为共享服务器中的所有用户带来严重的问题。除您之外的某个人可以编写脚本来读取这些文件,因此可以尝试从会话中取出值。


清单 7. 会话文件的内容
                
userName|s:5:"ngood";accountNumber|s:9:"123456789";


存储密码

不 管是在数据库、会话、文件系统中,还是在任何其他表单中,无论如何密码都决不能存储为纯文本。处理密码的最佳方法是将其加密存储并相互比较加密的密码。虽 然如此,在实践中人们仍然把密码存储到纯文本中。只要使用可以发送密码而非重置密码的 Web 站点,就意味着密码是存储在纯文本中或者可以获得用于解密的代码(如果加密的话)。即使是后者,也可以找到并使用解密代码。


您 可以采取两项操作来保护会话数据。第一是把您放入会话中的所有内容加密。但是正因为加密数据并不意味着绝对安全,因此请慎重采用这种方法作为保护会话的惟 一方式。备选方法是把会话数据存储在其他位置中,比方说数据库。您仍然必须确保锁定数据库,但是这种方法将解决两个问题:第一,它将把数据放到比共享文件 系统更加安全的位置;第二,它将使您的应用程序可以更轻松地跨越多个 Web 服务器,同时共享会话可以跨越多个主机。

要实现自己的会话 持久性,请参阅 PHP 中的 session_set_save_handler() 函数。使用它,您可以将会话信息存储在数据库中,也可以实现一个用于加密和解密所有数据的处理程序。清单 8 提供了实现的函数用法和函数骨架示例。您还可以在 参考资料 小节中查看如何使用数据库。


清单 8. session_set_save_handler() 函数示例
[php]                
function open($save_path, $session_name)
{
    /* custom code */
    return (true);
}

function close()
{
    /* custom code */
    return (true);
}

function read($id)
{
    /* custom code */
    return (true);
}

function write($id, $sess_data)
{
    /* custom code */
    return (true);
}

function destroy($id)
{
    /* custom code */
    return (true);
}

function gc($maxlifetime)
{
    /* custom code */
    return (true);
}

session_set_save_handler("open", "close", "read", "write", "destroy", "gc");[/php]

针对 XSS 漏洞进行保护

XSS 漏洞代表 2007 年所有归档的 Web 站点的大部分漏洞(请参阅 参考资料)。当用户能够把 HTML 代码注入到您的 Web 页面中时,就是出现了 XSS 漏洞。HTML 代码可以在脚本标记中携带 JavaScript 代码,因而只要提取页面就允许运行 JavaScript。清单 9 中的表单可以表示论坛、维基、社会网络或任何可以输入文本的其他站点。


清单 9. 输入文本的表单
[php]                


Your chance to input XSS








[/php]



清单 10 演示了允许 XSS 攻击的表单如何输出结果。


清单 10. showResults.php
[php]                


Results demonstrating XSS


echo("

You typed this:

");
echo("

");
echo($_POST['myText']);
echo("

");
?>

[/php]



清 单 11 提供了一个基本示例,在该示例中将弹出一个新窗口并打开 Google 的主页。如果您的 Web 应用程序不针对 XSS 攻击进行保护,则会造成严重的破坏。例如,某个人可以添加模仿站点样式的链接以达到欺骗(phishing)目的(请参阅 参考资料)。


清单 11. 恶意输入文本样例
[php]                
[/php]



要防止受到 XSS 攻击,只要变量的值将被打印到输出中,就需要通过 htmlentities() 函数过滤输入。记住要遵循第一个习惯:在 Web 应用程序的名称、电子邮件地址、电话号码和帐单信息的输入中用白名单中的值验证输入数据。

下面显示了更安全的显示文本输入的页面。


清单 12. 更安全的表单
[php]                


Results demonstrating XSS


echo("

You typed this:

");
echo("

");
echo(htmlentities($_POST['myText']));
echo("

");
?>

[/php]

针对无效 post 进行保护

表 单欺骗 是指有人把 post 从某个不恰当的位置发到您的表单中。欺骗表单的最简单方法就是创建一个通过提交至表单来传递所有值的 Web 页面。由于 Web 应用程序是没有状态的,因此没有一种绝对可行的方法可以确保所发布数据来自指定位置。从 IP 地址到主机名,所有内容都是可以欺骗的。清单 13 显示了允许输入信息的典型表单。


清单 13. 处理文本的表单
[php]                


Form spoofing example


if ($_POST['submit'] == 'Save') {
    echo("

I am processing your text: ");
    echo($_POST['myText']);
    echo("

");
}
?>

[/php]



清单 14 显示了将发布到清单 13 所示表单中的表单。要尝试此操作,您可以把该表单放到 Web 站点中,然后把清单 14 中的代码另存为桌面上的 HTML 文档。在保存表单后,在浏览器中打开该表单。然后可以填写数据并提交表单,从而观察如何处理数据。


清单 14. 收集数据的表单
[php]                


Collecting your data







[/php]



表单欺骗的潜在影响是,如果拥有含下拉框、单选按钮、复选框或其他限制输入的表单,则当表单被欺骗时这些限制没有任何意义。考虑清单 15 中的代码,其中包含带有无效数据的表单。


清单 15. 带有无效数据的表单
[php]                


Collecting your data


    method="post">    value="There is no way this is a valid response to a yes/no answer..." />



[/php]



思 考一下:如果拥有限制用户输入量的下拉框或单选按钮,您可能会认为不用担心验证输入的问题。毕竟,输入表单将确保用户只能输入某些数据,对吧?要限制表单 欺骗,需要进行验证以确保发布者的身份是真实的。您可以使用一种一次性使用标记,虽然这种技术仍然不能确保表单绝对安全,但是会使表单欺骗更加困难。由于 在每次调用表单时都会更改标记,因此想要成为攻击者就必须获得发送表单的实例,去掉标记,并把它放到假表单中。使用这项技术可以阻止恶意用户构建持久的 Web 表单来向应用程序发布不适当的请求。清单 16 提供了一种表单标记示例。


清单 16. 使用一次性表单标记
[php]                
session_start();
?>


SQL Injection Test



echo 'Session token=' . $_SESSION['token'];
echo '
';
echo 'Token from form=' . $_POST['token'];
echo '
';

if ($_SESSION['token'] == $_POST['token']) {
    /* cool, it's all good... create another one */

} else {
    echo '

Go away!

';
}
$token = md5(uniqid(rand(), true));
$_SESSION['token'] = $token;
?>
    method="post">

    value="" />



[/php]

针对 CSRF 进行保护

跨 站点请求伪造(CSRF 攻击)是利用用户权限执行攻击的结果。在 CSRF 攻击中,您的用户可以轻易地成为预料不到的帮凶。清单 17 提供了执行特定操作的页面示例。此页面将从 cookie 中查找用户登录信息。只要 cookie 有效,Web 页面就会处理请求。


清单 17. CSRF 示例
[php]                
PHP安全编程[/php]



CSRF 攻击通常是以 PHP安全编程 标记的形式出现的,因为浏览器将在不知情的情况下调用该 URL 以获得图像。但是,图像来源可以是根据传入参数进行处理的同一个站点中的页面 URL。当此 PHP安全编程 标记与 XSS 攻击结合在一起时 ? 在已归档的攻击中最常见 ? 用户可以在不知情的情况下轻松地对其凭证执行一些操作 ? 因此是伪造的。

为了保护您免受 CSRF 攻击,需要使用在检验表单 post 时使用的一次性标记方法。此外,使用显式的 $_POST 变量而非 $_REQUEST。清单 18 演示了处理相同 Web 页面的糟糕示例 ? 无论是通过 GET 请求调用页面还是通过把表单发布到页面中。


清单 18. 从 $_REQUEST 中获得数据
[php]                


Processes both posts AND gets


if ($_REQUEST['submit'] == 'Save') {
    echo("

I am processing your text: ");
    echo(htmlentities($_REQUEST['text']));
    echo("

");
}
?>

[/php]



清单 19 显示了只使用表单 POST 的干净页面。


清单 19. 仅从 $_POST 中获得数据
[php]                


Processes both posts AND gets


if ($_POST['submit'] == 'Save') {
    echo("

I am processing your text: ");
    echo(htmlentities($_POST['text']));
    echo("

");
}
?>

[/php]

结束语

从这七个习惯开始尝试编写更安全的 PHP Web 应用程序,可以帮助您避免成为恶意攻击的受害者。和许多其他习惯一样,这些习惯最开始可能很难适应,但是随着时间的推移遵循这些习惯会变得越来越自然。

记住第一个习惯是关键:验证输入。在确保输入不包括无效值之后,可以继续保护文件系统、数据库和会话。最后,确保 PHP 代码可以抵抗 XSS 攻击、表单欺骗和 CSRF 攻击。形成这些习惯后可以帮助您抵御一些简单的攻击。
성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
과대 광고 : 오늘 PHP의 역할을 평가합니다과대 광고 : 오늘 PHP의 역할을 평가합니다Apr 12, 2025 am 12:17 AM

PHP는 현대적인 프로그래밍, 특히 웹 개발 분야에서 강력하고 널리 사용되는 도구로 남아 있습니다. 1) PHP는 사용하기 쉽고 데이터베이스와 완벽하게 통합되며 많은 개발자에게 가장 먼저 선택됩니다. 2) 동적 컨텐츠 생성 및 객체 지향 프로그래밍을 지원하여 웹 사이트를 신속하게 작성하고 유지 관리하는 데 적합합니다. 3) 데이터베이스 쿼리를 캐싱하고 최적화함으로써 PHP의 성능을 향상시킬 수 있으며, 광범위한 커뮤니티와 풍부한 생태계는 오늘날의 기술 스택에 여전히 중요합니다.

PHP의 약한 참고 자료는 무엇이며 언제 유용합니까?PHP의 약한 참고 자료는 무엇이며 언제 유용합니까?Apr 12, 2025 am 12:13 AM

PHP에서는 약한 참조가 약한 회의 클래스를 통해 구현되며 쓰레기 수집가가 물체를 되 찾는 것을 방해하지 않습니다. 약한 참조는 캐싱 시스템 및 이벤트 리스너와 같은 시나리오에 적합합니다. 물체의 생존을 보장 할 수 없으며 쓰레기 수집이 지연 될 수 있음에 주목해야합니다.

PHP의 __invoke 마법 방법을 설명하십시오.PHP의 __invoke 마법 방법을 설명하십시오.Apr 12, 2025 am 12:07 AM

\ _ \ _ 호출 메소드를 사용하면 객체를 함수처럼 호출 할 수 있습니다. 1. 객체를 호출 할 수 있도록 메소드를 호출하는 \ _ \ _ 정의하십시오. 2. $ obj (...) 구문을 사용할 때 PHP는 \ _ \ _ invoke 메소드를 실행합니다. 3. 로깅 및 계산기, 코드 유연성 및 가독성 향상과 같은 시나리오에 적합합니다.

동시성에 대해 PHP 8.1의 섬유를 설명하십시오.동시성에 대해 PHP 8.1의 섬유를 설명하십시오.Apr 12, 2025 am 12:05 AM

섬유는 PHP8.1에 도입되어 동시 처리 기능을 향상시켰다. 1) 섬유는 코 루틴과 유사한 가벼운 동시성 모델입니다. 2) 개발자는 작업의 실행 흐름을 수동으로 제어 할 수 있으며 I/O 집약적 작업을 처리하는 데 적합합니다. 3) 섬유를 사용하면보다 효율적이고 반응이 좋은 코드를 작성할 수 있습니다.

PHP 커뮤니티 : 자원, 지원 및 개발PHP 커뮤니티 : 자원, 지원 및 개발Apr 12, 2025 am 12:04 AM

PHP 커뮤니티는 개발자 성장을 돕기 위해 풍부한 자원과 지원을 제공합니다. 1) 자료에는 공식 문서, 튜토리얼, 블로그 및 Laravel 및 Symfony와 같은 오픈 소스 프로젝트가 포함됩니다. 2) 지원은 StackoverFlow, Reddit 및 Slack 채널을 통해 얻을 수 있습니다. 3) RFC에 따라 개발 동향을 배울 수 있습니다. 4) 적극적인 참여, 코드에 대한 기여 및 학습 공유를 통해 커뮤니티에 통합 될 수 있습니다.

PHP vs. Python : 차이점 이해PHP vs. Python : 차이점 이해Apr 11, 2025 am 12:15 AM

PHP와 Python은 각각 고유 한 장점이 있으며 선택은 프로젝트 요구 사항을 기반으로해야합니다. 1.PHP는 간단한 구문과 높은 실행 효율로 웹 개발에 적합합니다. 2. Python은 간결한 구문 및 풍부한 라이브러리를 갖춘 데이터 과학 및 기계 학습에 적합합니다.

PHP : 죽어 가거나 단순히 적응하고 있습니까?PHP : 죽어 가거나 단순히 적응하고 있습니까?Apr 11, 2025 am 12:13 AM

PHP는 죽지 않고 끊임없이 적응하고 진화합니다. 1) PHP는 1994 년부터 새로운 기술 트렌드에 적응하기 위해 여러 버전 반복을 겪었습니다. 2) 현재 전자 상거래, 컨텐츠 관리 시스템 및 기타 분야에서 널리 사용됩니다. 3) PHP8은 성능과 현대화를 개선하기 위해 JIT 컴파일러 및 기타 기능을 소개합니다. 4) Opcache를 사용하고 PSR-12 표준을 따라 성능 및 코드 품질을 최적화하십시오.

PHP의 미래 : 적응 및 혁신PHP의 미래 : 적응 및 혁신Apr 11, 2025 am 12:01 AM

PHP의 미래는 새로운 기술 트렌드에 적응하고 혁신적인 기능을 도입함으로써 달성 될 것입니다. 1) 클라우드 컴퓨팅, 컨테이너화 및 마이크로 서비스 아키텍처에 적응, Docker 및 Kubernetes 지원; 2) 성능 및 데이터 처리 효율을 향상시키기 위해 JIT 컴파일러 및 열거 유형을 도입합니다. 3) 지속적으로 성능을 최적화하고 모범 사례를 홍보합니다.

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
4 몇 주 전By尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

MinGW - Windows용 미니멀리스트 GNU

MinGW - Windows용 미니멀리스트 GNU

이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

에디트플러스 중국어 크랙 버전

에디트플러스 중국어 크랙 버전

작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음

SublimeText3 Linux 새 버전

SublimeText3 Linux 새 버전

SublimeText3 Linux 최신 버전