搜索
首页后端开发php教程使用Phroute快速php路由

使用Phroute快速php路由

Phroute是一个有趣的软件包:这是一款基于正则表达式的快速路由器,您可以在中小型项目中轻松实现。但是,它不仅很快:有过滤器,过滤器组和命名路线。如果情况越来越大,您也可以使用基本的控制器系统。

也就是说,今天我们将看到如何使用它以及如何在示例项目中实现其功能。另外,我们将看到引擎盖下的内容:Phroute是不同人进行的许多实验和测试的结果。

让我们从安装它开始!

钥匙要点

PhRoute是一个高效的,基于正则义务的路由套件,非常适合中小型PHP项目,为较大应用提供过滤器,过滤器组和基本控制器系统等功能。>>> 使用作曲家,Phroute的安装很简单,增强了项目设置速度和简单性。

> phroute支持各种HTTP方法,并允许使用可选参数进行动态路由,使其用于API开发和其他Web应用程序。 可以在路由处理之前或之后使用phroute中的过滤器,为访问控制和数据验证提供功能强大的工具,增强安全性和数据完整性。>
    > Phroute在路由性能方面表现出色,大大优于其他一些路由器,例如Laravel's,但目前缺乏高级控制器功能和全面的文档,即确定的未来改进领域。
  • >安装
  • >您可以在几秒钟内使用作曲家将Phroute添加到您的项目中。只需将此行添加到您的composer.json文件:
  • 键入Composer install命令,您正在加入。现在,让我们继续进行测试项目。>
  • 示例项目和第一个示例
  • 为了更好地理解Phroute的每个概念,最好与示例项目一起工作。今天,我们将为书籍数据库服务做一个基本的API。
  • 这是我们将要使用的数据库方案:

如果您想进行一些测试,这是我使用的SQL模式转储(带有一些额外的虚拟数据)。

>
{ 
        "require": 
        { 
            "phroute/phroute": "1.*" 
        } 
    }

我们不会写任何真正复杂的东西。实际上,编写一些以非常基本的方式模拟API请求的路线就足够了。如果您想写一个真实的API,您必须知道很多概念,但是今天我们只是看一下Phroute。

在我们从特定路线开始之前,让我们分析主要的应用结构。这就是我们将要放入index.php文件中的内容。

>

我们有三种实用程序方法:ProcessInput,ProcessOutput和GetPdoInstance。我们将使用前两个来确保我们获得正确的输入和正确的输出。第三个将准备必要的PDO实例。

注意:由于我的个人特定项目设置,Array_Slice方法的第二个参数为“ 3”。随着基本URL的变化而更改它。

在那之后,我们使用对象$路由器(RouteController类的实例)声明路线。然后,魔术发生在$ dispatcher-> dispatch()方法中,该方法采用两个参数:$ _server请求方法(获取,发布等)和特定的请求URI。有了这些信息,调度员将调用正确的路线并在关闭中执行代码。返回值存储在$响应变量中,该变量给出了将其作为JSON字符串回声的方法processOutput()。 如您所见,在此特定示例中,我们声明了一个路线:hello。

>注意:但是,如果需要,可以增强实际结构。创建一个新文件并调用routes.php。然后,在$路由器对象初始化之后,将其从Main Index.php文件中包含:您将在单独的文件中使用所有路由。在我看来,一个更优雅的解决方案。

>

也就是说,您现在知道有关我们示例的基本结构所需的一切。>

让我们做我们的第一条路线!

>

路由

一个简单的路线

好吧,让我们看看我们可以通过路线以及可以为我们的需求定制多少路线。

我们是从最简单的事情开始的:作者列表。

在第一行中,我们声明了我们的路线名称,作者。

>让我们测试路线:这是结果。
{ 
        "require": 
        { 
            "phroute/phroute": "1.*" 
        } 
    }
>

好!

添加一个参数
<span>CREATE TABLE IF NOT EXISTS authors (id int(10) unsigned NOT NULL AUTO_INCREMENT, name varchar(250) NOT NULL, PRIMARY KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3;
</span>
    <span>INSERT INTO authors (id, name) 
</span>    <span>VALUES 
</span>    <span>(1, 'Dan Brown'), 
</span>    <span>(2, 'Paulo Coelho');
</span>
    <span>CREATE TABLE IF NOT EXISTS categories (id int(10) unsigned NOT NULL AUTO_INCREMENT, name varchar(250) NOT NULL, PRIMARY KEY (id)) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=3;
</span>
    <span>INSERT INTO categories (id, name) 
</span>    <span>VALUES 
</span>    <span>(1, 'Thriller'), 
</span>    <span>(2, 'Novel');
</span>
    <span>CREATE TABLE IF NOT EXISTS books (id int(10) unsigned NOT NULL AUTO_INCREMENT,   title varchar(250) NOT NULL, isbn varchar(50) NOT NULL, year int(11) NOT NULL,   pages int(11) NOT NULL, author_id int(10) unsigned NOT NULL, category_id int(10) unsigned NOT NULL, PRIMARY KEY (id), KEY author_id (author_id,category_id), KEY category_id (category_id)) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=7;
</span>
    <span>INSERT INTO books (id, title, isbn, year, pages, author_id, category_id) 
</span>    <span>VALUES 
</span>    <span>(1, 'The Zahir', '0-06-083281-9', 2005, 336, 2, 2), 
</span>    <span>(2, 'The Devil and Miss Prym', '0-00-711605-5', 2000, 205, 2, 2), 
</span>    <span>(3, 'The Alchemist', '0-06-250217-4', 1988, 163, 2, 2), 
</span>    <span>(4, 'Inferno', '978-0-385-53785-8', 2013, 480, 1, 1), 
</span>    <span>(5, 'The Da Vinci Code', '0-385-50420-9', 2003, 454, 1, 1), 
</span>    <span>(6, 'Angels & Demons', '0-671-02735-2', 2000, 616, 1, 1);</span>

>现在我们可以向前迈出一步:添加一个参数,以获取单个作者的详细信息,给定ID?

类似的东西:

>您可以使用{variable_name}占位符传递参数,并以相同的选择名称作为闭合参数。在此示例中,我们有一个与$ id参数相对应的{id}占位符。您可以指定所需的任何参数:无限制。

有时,参数是可选的。让我们举一个例子:如果我们使用书籍URL,我们想检索所有数据库书的列表。但是,如果我们指定ID之类的书籍/1,我们将获得给定类别的书籍列表。

>

在这里我们去:
<span><span><?php </span></span><span>
</span><span>    <span>require 'vendor/autoload.php';
</span></span><span>
</span><span>    <span>function processInput($uri){        
</span></span><span>        <span>$uri = implode('/', 
</span></span><span>            <span>array_slice(
</span></span><span>                <span>explode('/', $_SERVER['REQUEST_URI']), 3));         
</span></span><span>
</span><span>            <span>return $uri;    
</span></span><span>    <span>}
</span></span><span>
</span><span>    <span>function processOutput($response){
</span></span><span>        <span>echo json_encode($response);    
</span></span><span>    <span>}
</span></span><span>
</span><span>    <span>function getPDOInstance(){
</span></span><span>        <span>return new PDO('mysql:host=localhost;dbname=booksapi;charset=utf8', 'root', '');
</span></span><span>    <span>}
</span></span><span>
</span><span>    <span>$router = new Phroute<span>\RouteCollector</span>(new Phroute<span>\RouteParser</span>);
</span></span><span>
</span><span>    <span>$router->get('hello', function(){ 
</span></span><span>        <span>return 'Hello, PHRoute!';   
</span></span><span>    <span>});
</span></span><span>
</span><span>    <span>$dispatcher = new Phroute<span>\Dispatcher</span>(router);
</span></span><span>
</span><span>    <span>try {
</span></span><span>
</span><span>        <span>$response = $dispatcher->dispatch($_SERVER['REQUEST_METHOD'], processInput($_SERVER['REQUEST_URI']));
</span></span><span>
</span><span>    <span>} catch (Phroute<span>\Exception\HttpRouteNotFoundException</span> $e) {
</span></span><span>
</span><span>        <span>var_dump($e);      
</span></span><span>        <span>die();
</span></span><span>
</span><span>    <span>} catch (Phroute<span>\Exception\HttpMethodNotAllowedException</span> $e) {
</span></span><span>
</span><span>        <span>var_dump($e);       
</span></span><span>        <span>die();
</span></span><span>
</span><span>    <span>}
</span></span><span>
</span><span>    <span>processOutput($response);</span></span></span>

添加“?”在参数占位符之后,意味着它将是可选的。当然,最好在“关闭声明”中指定默认值。

使用不同的动词

>到目前为止,我们仅创建了路由。那其他http动词呢?

<span>$router->get('authors', function(){      
</span>        <span>$db = getPDOInstance();
</span>
        <span>$sql = 'SELECT * FROM authors;';  
</span>        <span>$st = $db->prepare($sql, array(PDO<span>::</span>ATTR_CURSOR => PDO<span>::</span>CURSOR_FWDONLY));
</span>
        <span>$st->execute();
</span>
        <span>$result = $st->fetchAll(PDO<span>::</span>FETCH_CLASS);
</span>	    
        <span>return $result;  
</span>    <span>});</span>
没问题。在这里看看:

>让我们做一个示例邮寄路线。是时候在我们的收藏中添加一本新书了!

>

>让我们想象我们有一个表格可以填写书籍数据:其动作属性将指向我们现在创建的书籍路线!

>

>现在我们将迈出又一步:是时候“保护”我们的路线!

>过滤

实际上,进入书籍邮政路线的每个人都可以在我们的收藏中插入一本新书。这很酷,但这通常不像事情发生。如果我们想保护自己的路线怎么办?过滤器是我们需要的。

>过滤器与路线非常相似:它们具有名称和关联的闭合,当过滤器被称为某个地方时执行。

>那么,有什么区别?可以在路由之前(或之后)轻松调用过滤器。

>

>过滤

让我们以一个示例:

首先,我们用$路由器对象的filter()方法声明了过滤器。语法与路线相同。我们给它一个名称和封闭,将在正确的时间执行。
{ 
        "require": 
        { 
            "phroute/phroute": "1.*" 
        } 
    }
>

好,但是什么是“正确的时间”?

我们现在正在决定:我们只是在post()方法中添加了第三个参数。第三个参数是一个数组,我们在其中使用过滤器的名称(logged_in)指定键。从这一刻开始,在每次呼叫邮寄路由之前,也将调用logged_in filter(并执行其闭合内容)。

>

在这种特定情况下,我们正在检查一个会话user_id变量,以查看用户是否已登录。

>

>在路由呼叫之后,也有用于运行过滤器的后键。这是一个例子。

如果需要,也可以同时指定多个过滤器。

您所要做的就是使用一系列字符串而不是单个字符串。
<span>CREATE TABLE IF NOT EXISTS authors (id int(10) unsigned NOT NULL AUTO_INCREMENT, name varchar(250) NOT NULL, PRIMARY KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3;
</span>
    <span>INSERT INTO authors (id, name) 
</span>    <span>VALUES 
</span>    <span>(1, 'Dan Brown'), 
</span>    <span>(2, 'Paulo Coelho');
</span>
    <span>CREATE TABLE IF NOT EXISTS categories (id int(10) unsigned NOT NULL AUTO_INCREMENT, name varchar(250) NOT NULL, PRIMARY KEY (id)) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=3;
</span>
    <span>INSERT INTO categories (id, name) 
</span>    <span>VALUES 
</span>    <span>(1, 'Thriller'), 
</span>    <span>(2, 'Novel');
</span>
    <span>CREATE TABLE IF NOT EXISTS books (id int(10) unsigned NOT NULL AUTO_INCREMENT,   title varchar(250) NOT NULL, isbn varchar(50) NOT NULL, year int(11) NOT NULL,   pages int(11) NOT NULL, author_id int(10) unsigned NOT NULL, category_id int(10) unsigned NOT NULL, PRIMARY KEY (id), KEY author_id (author_id,category_id), KEY category_id (category_id)) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=7;
</span>
    <span>INSERT INTO books (id, title, isbn, year, pages, author_id, category_id) 
</span>    <span>VALUES 
</span>    <span>(1, 'The Zahir', '0-06-083281-9', 2005, 336, 2, 2), 
</span>    <span>(2, 'The Devil and Miss Prym', '0-00-711605-5', 2000, 205, 2, 2), 
</span>    <span>(3, 'The Alchemist', '0-06-250217-4', 1988, 163, 2, 2), 
</span>    <span>(4, 'Inferno', '978-0-385-53785-8', 2013, 480, 1, 1), 
</span>    <span>(5, 'The Da Vinci Code', '0-385-50420-9', 2003, 454, 1, 1), 
</span>    <span>(6, 'Angels & Demons', '0-671-02735-2', 2000, 616, 1, 1);</span>
>


>滤波器组

<span><span><?php </span></span><span>
</span><span>    <span>require 'vendor/autoload.php';
</span></span><span>
</span><span>    <span>function processInput($uri){        
</span></span><span>        <span>$uri = implode('/', 
</span></span><span>            <span>array_slice(
</span></span><span>                <span>explode('/', $_SERVER['REQUEST_URI']), 3));         
</span></span><span>
</span><span>            <span>return $uri;    
</span></span><span>    <span>}
</span></span><span>
</span><span>    <span>function processOutput($response){
</span></span><span>        <span>echo json_encode($response);    
</span></span><span>    <span>}
</span></span><span>
</span><span>    <span>function getPDOInstance(){
</span></span><span>        <span>return new PDO('mysql:host=localhost;dbname=booksapi;charset=utf8', 'root', '');
</span></span><span>    <span>}
</span></span><span>
</span><span>    <span>$router = new Phroute<span>\RouteCollector</span>(new Phroute<span>\RouteParser</span>);
</span></span><span>
</span><span>    <span>$router->get('hello', function(){ 
</span></span><span>        <span>return 'Hello, PHRoute!';   
</span></span><span>    <span>});
</span></span><span>
</span><span>    <span>$dispatcher = new Phroute<span>\Dispatcher</span>(router);
</span></span><span>
</span><span>    <span>try {
</span></span><span>
</span><span>        <span>$response = $dispatcher->dispatch($_SERVER['REQUEST_METHOD'], processInput($_SERVER['REQUEST_URI']));
</span></span><span>
</span><span>    <span>} catch (Phroute<span>\Exception\HttpRouteNotFoundException</span> $e) {
</span></span><span>
</span><span>        <span>var_dump($e);      
</span></span><span>        <span>die();
</span></span><span>
</span><span>    <span>} catch (Phroute<span>\Exception\HttpMethodNotAllowedException</span> $e) {
</span></span><span>
</span><span>        <span>var_dump($e);       
</span></span><span>        <span>die();
</span></span><span>
</span><span>    <span>}
</span></span><span>
</span><span>    <span>processOutput($response);</span></span></span>
>让我们想象一个现实世界的案例:假设我们有三个邮政路线,一个针对每个实体(作者,书籍,类别)。添加logged_in滤波器三个不同的时间会很无聊。

>

不用担心:滤镜组在这里提供帮助。

>

使用此组,我们为三个不同的路由定义了相同的滤镜。

注意:如果需要,您也可以在其他组中嵌套成组。
<span>$router->get('authors', function(){      
</span>        <span>$db = getPDOInstance();
</span>
        <span>$sql = 'SELECT * FROM authors;';  
</span>        <span>$st = $db->prepare($sql, array(PDO<span>::</span>ATTR_CURSOR => PDO<span>::</span>CURSOR_FWDONLY));
</span>
        <span>$st->execute();
</span>
        <span>$result = $st->fetchAll(PDO<span>::</span>FETCH_CLASS);
</span>	    
        <span>return $result;  
</span>    <span>});</span>

增长项目?是时候使用控制器了!

>我们的项目正在成长,并在一个文件中组织我们的代码库真的很重,很草率。使用控制器呢?

>

是:phroute不仅与路线有关。当事情变得疯狂时,是时候组织了它们了。

首先,让我们看看控制器的结构是什么样的。看看这个示例(我们可以将其放在我们的routes.php文件中):>

我们创建了一个作者类。在此类中,我们放了两种方法:getIndex()和postadd()。

> 然后,使用$ Router对象的Controller()方法,我们将作者URL链接到作者类。因此,如果我们在浏览器中输入URL作者,则将自动调用GetIndex()方法。 postadd()方法也将绑定到作者/add(post)URL。

这个自动解析名称功能非常有趣,但实际上还不够。

>

>控制器部分处于开发的早期阶段,需要进行许多改进。其中之一是可以为控制器方法定义参数。或者,也许是为某些控制器的某些方法定义过滤器的简便方法(而不是“全部或全部”)。

>

结论

>有很多工作要做,尤其是在控制器方面。作为开发人员,我认为拥有一个通用的基本控制器类来处理所有肮脏的工作(使用过滤器,方法参数等)将是很棒的。也缺乏文档。

另一方面,Phroute配备了一个非常快速的路由器。在项目的GitHub页面上,您可以看到有关与Laravel的核心路由器进行比较的一些统计数据:结果很棒。在最坏的情况下

>如果您想了解该路由器背后的“引擎”的特定详细信息,则可以访问Github上的Nikic页面,他在其中解释了所有努力,并提供了测试,基准和相关结果。

您要尝试phroute吗?让我知道您对此有何看法!

>常见问题(常见问题解答)有关使用PHROUTE

快速php路由的问题

什么是phroute,为什么在PHP路由中很重要?它在PHP路由中很重要,因为它提供了一种简单便捷的方法来定义PHP应用程序中的路由。 PHROUTE允许您将URL映射到应用程序中的特定功能或方法,从而更容易管理和组织代码。它还支持路由参数和过滤器,使您可以更多地控制应用程序如何响应不同的URL。

>

>我如何在我的PHP应用程序中安装phroute?

>

phroute可以轻松地安装在您的PHROUTE中PHP应用程序使用Composer,Composer是PHP的依赖关系管理工具。您可以在其官方网站上按照说明来安装作曲家。安装了作曲家后,您可以通过在终端中运行以下命令来安装PHROUTE:COMPOSER需要Phroute/Phroute。这将在您的应用程序中下载并安装phroute。

如何使用phroute?

使用Phroute定义路由很简单。您首先需要创建一个PhrouterOuteCollector类的实例。然后,您可以使用此类的路由方法来定义路线。路由方法采用三个参数:HTTP方法(GET,POST等),URL模式和处理程序函数或方法。这是一个示例:

$ router = new phrouteroutecollector(); $ router-> route('get',','/uster/users/{id}',function($ id) “用户ID:$ id”;

});

>如何使用phroute?

路由参数处理路由参数,路由参数是URL的一部分。在PHROUTE中,您可以在定义路由时将路由参数包括在URL模式中来定义路由参数。路由参数包含在卷曲括号{}中。匹配路由时,路由参数的值将传递给处理程序函数或方法作为参数。这是一个示例:

$ router = new phrouteroutecollector(); $ router-> route('get',','/uster/users/{id}',function($ id) “用户ID:$ id”;
});

>如何将过滤器与phroute一起使用? PHROUTE是在匹配路线之前或之后运行的函数或方法。它们可用于执行身份验证或输入验证等任务。您可以使用PhrouterOuteCollector类的过滤器方法来定义过滤器,并且可以使用前后方法将其应用于路由。这是一个示例:

$ router = new phrouteroutecollector();

$ router-> filter('auth',function',function(){

> if(! )){
返回false;
}
});
$ router-> route('get','/dashboard', ['dashboard Controller','show']) - >>>之前('auth');

>如何处理phroute的404错误?

$ router = new PhrouterOuteCollector();

$ router-> notfound(function(){返回'404- dege not -page not of endure';

});
>如何使用phroute?

派遣路由,一旦定义了路线,就可以使用phroute? PHROUTOROUTEDISPATCHER类。此类的调度方法将HTTP方法和URL作为参数,并返回匹配的路由的处理程序功能或方法的结果。这是一个示例:

$ dispatcher = new phrouteroutedispatcher($ router-> getData());

$ recession = $ dispatcher-> dispatcher-> dispatch($ _ server ['request_method'],$ _server [ ']));

echo $ response;


>我可以与其他phroute一起使用PHP Frameworks?

是的,您可以将PHROUTE与其他PHP框架一起使用。 Phroute是一个独立的库,这意味着它不依赖于任何特定的框架。无论您使用的框架如何,您都可以在任何PHP应用程序中使用它。但是,您可能需要调整代码以与框架的路由系统一起工作。
>

>如何使用PhrouterOuteCollector类的调试方法来完成Phroute中的调试路由?此方法返回所有定义的路由的数组,这对于调试目的可能很有用。这是一个示例:

$ router = new phrouteroutecollector(); $ router-> route('get',','/uster/users/{id}',function($ id) “用户ID:$ id”;
});
print_r($ router-> debug());

如何处理可以通过将您的调度代码包装在try-catch块中来处理PhRoute?

的异常。如果在调度过程中抛出异常,则可以捕获并适当处理它。以下是一个示例:

尝试{

$ dispatcher = new phrouteroutedispatcher($ router-> getData()); $ recession = $ dispert = $ dispather-> dispatch($ _ servert($ _ servers ['umplect_method''],'umplect_method'],,,,美元$ e){ echo'发生错误:'。 $ e-> getMessage();
}

以上是使用Phroute快速php路由的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
在Laravel中使用Flash会话数据在Laravel中使用Flash会话数据Mar 12, 2025 pm 05:08 PM

Laravel使用其直观的闪存方法简化了处理临时会话数据。这非常适合在您的应用程序中显示简短的消息,警报或通知。 默认情况下,数据仅针对后续请求: $请求 -

php中的卷曲:如何在REST API中使用PHP卷曲扩展php中的卷曲:如何在REST API中使用PHP卷曲扩展Mar 14, 2025 am 11:42 AM

PHP客户端URL(curl)扩展是开发人员的强大工具,可以与远程服务器和REST API无缝交互。通过利用Libcurl(备受尊敬的多协议文件传输库),PHP curl促进了有效的执行

简化的HTTP响应在Laravel测试中模拟了简化的HTTP响应在Laravel测试中模拟了Mar 12, 2025 pm 05:09 PM

Laravel 提供简洁的 HTTP 响应模拟语法,简化了 HTTP 交互测试。这种方法显着减少了代码冗余,同时使您的测试模拟更直观。 基本实现提供了多种响应类型快捷方式: use Illuminate\Support\Facades\Http; Http::fake([ 'google.com' => 'Hello World', 'github.com' => ['foo' => 'bar'], 'forge.laravel.com' =>

在Codecanyon上的12个最佳PHP聊天脚本在Codecanyon上的12个最佳PHP聊天脚本Mar 13, 2025 pm 12:08 PM

您是否想为客户最紧迫的问题提供实时的即时解决方案? 实时聊天使您可以与客户进行实时对话,并立即解决他们的问题。它允许您为您的自定义提供更快的服务

PHP记录:PHP日志分析的最佳实践PHP记录:PHP日志分析的最佳实践Mar 10, 2025 pm 02:32 PM

PHP日志记录对于监视和调试Web应用程序以及捕获关键事件,错误和运行时行为至关重要。它为系统性能提供了宝贵的见解,有助于识别问题并支持更快的故障排除

解释PHP中晚期静态结合的概念。解释PHP中晚期静态结合的概念。Mar 21, 2025 pm 01:33 PM

文章讨论了PHP 5.3中引入的PHP中的晚期静态结合(LSB),从而允许静态方法的运行时分辨率调用以获得更灵活的继承。 LSB的实用应用和潜在的触摸

在Laravel中发现文件下载的存储::下载在Laravel中发现文件下载的存储::下载Mar 06, 2025 am 02:22 AM

Laravel框架的Storage::download方法提供了一个简洁的API,用于安全地处理文件下载,同时管理文件存储的抽象。 以下是一个在示例控制器中使用Storage::download()的例子:

如何注册和使用Laravel服务提供商如何注册和使用Laravel服务提供商Mar 07, 2025 am 01:18 AM

Laravel的服务容器和服务提供商是其架构的基础。 本文探讨了服务容器,详细信息服务提供商创建,注册,并通过示例演示了实际用法。 我们将从OVE开始

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热工具

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。