찾다
백엔드 개발PHP 튜토리얼关于php中的spl_autoload_register,splautoloadregister_PHP教程

关于php中的spl_autoload_register,splautoloadregister

一、自动加载定义

很多开发者写面向对象的应用程序时对每个类的定义建立一个 PHP 源文件。一个很大的烦恼是不得不在每个脚本开头写一个长长的包含文件列表(每个类一个文件)。

在 PHP 5 中,不再需要这样了。可以定义一个 __autoload() 函数,它会在试图使用尚未被定义的类时自动调用。通过调用此函数,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类

__autoload 是一个魔术方法, 尝试加载未定义的类,spl_autoload_register - 注册给定的函数作为 __autoload 的实现

<p class="para"><span class="function"><span class="tip"><span class="tip">Tip</span></span></span></p>
<p class="para"><span class="function">spl_autoload_register() 提供了一种更加灵活的方式来实现类的自动加载。因此,不再建议使用 <span class="function">__autoload()函数,在以后的版本中它可能被弃用。</span></span></p>

Note:

在 5.3.0 版之前,__autoload 函数抛出的异常不能被 catch 语句块捕获并会导致一个致命错误。从 5.3.0+ 之后,__autoload 函数抛出的异常可以被 catch 语句块捕获,但需要遵循一个条件。如果抛出的是一个自定义异常,那么必须存在相应的自定义异常类。__autoload 函数可以递归的自动加载自定义异常类。

Note:

自动加载不可用于 PHP 的 CLI 交互模式。

Note:

如果类名比如被用于 call_user_func(),则它可能包含一些危险的字符,比如 ../。 建议您在这样的函数中不要使用用户的输入,起码需要在 __autoload() 时验证下输入

二、spl_autoload_register

目录

classes --+
          + mail.class.php
          + norman.class.php
          + db.class.php

1、Single Autoloads

<?php
    /*** nullify any existing autoloads ***/
    spl_autoload_register(null, false);

    /*** specify extensions that may be loaded ***/
    spl_autoload_extensions('.php, .class.php');

    /*** class Loader ***/
    function classLoader($class)
    {
        $filename = strtolower($class) . '.class.php';
        $file ='classes/' . $filename;
        if (!file_exists($file))
        {
            return false;
        }
        include $file;
    }

    /*** register the loader functions ***/
    spl_autoload_register('classLoader');

    /*** a new instance if norman ***/
    $norman = new norman;

    /*** make norman do something ***/
    $norman->do_something();
?>

2、Mulitple Autoloads

<?php

    /*** nullify any existing autoloads ***/
    spl_autoload_register(null, false);

    /*** specify extensions that may be loaded ***/
    spl_autoload_extensions('.php, .class.php, .lib.php');

    /*** class Loader ***/
    function classLoader($class)
    {
        $filename = strtolower($class) . '.class.php';
        $file ='classes/' . $filename;
        if (!file_exists($file))
        {
            return false;
        }
        include $file;
    }

    function libLoader($class)
    {
        $filename = strtolower($class) . '.lib.php';
        $file ='libs/' . $filename;
        if (!file_exists($file))
        {
            return false;
        }
        include $file;
    }

    /*** register the loader functions ***/
    spl_autoload_register('classLoader');
    spl_autoload_register('libLoader');

    /*** a new instance of norman ***/
    $norman = new norman;

    /*** make norman do some thing ***/
    $norman->do_something();

3、Interfaces

接口文件

<?php
    /*
     * icontroller.class.php
     * interface to ensure all classes have an index method
     *
     */
    interface iController
    {
        public function index();
    }
?>

autoload文件

<?php
    /*** nullify any existing autoloads ***/
    spl_autoload_register(null, false);

    /*** specify extensions that may be loaded ***/
    spl_autoload_extensions('.php, .class.php');

    /*** class Loader ***/
    function classLoader($class)
    {
        $filename = strtolower($class) . '.class.php';
        $file ='classes/' . $filename;
        if (!file_exists($file))
        {
            return false;
        }
        include $file;
    }

    /*** register the loader functions ***/
    spl_autoload_register('classLoader');

    class blog implements iController
    {
        public function index()
        {
            echo 'hello from the index';
        }
    }

    /*** a new blog instance ***/
    $blog = new blog;

    /*** run the index method ***/
    $blog->index();
?>

4、一个标准的示例

spl_autoload_register( 'autoload' );
 
  
  /**
   * autoload
   *
   * @author testdd
   * @param  string $class
   * @param  string $dir
   * @return bool
   */
  function autoload( $class, $dir = null ) {
 
    if ( is_null( $dir ) )
      $dir = '/path/to/project';
 
    foreach ( scandir( $dir ) as $file ) {
 
      // directory?
      if ( is_dir( $dir.$file ) && substr( $file, 0, 1 ) !== '.' )
        autoload( $class, $dir.$file.'/' );
 
      // php file?
      if ( substr( $file, 0, 2 ) !== '._' && preg_match( "/.php$/i" , $file ) ) {
 
        // filename matches class?
        if ( str_replace( '.php', '', $file ) == $class || str_replace( '.class.php', '', $file ) == $class ) {
 
            include $dir . $file;
        }
      }
    }
  }

5、框架中的写法

<?php
/**
 * Autoloader
 * @author Jianxiang Qin <TalkativeDoggy@gmail.com>
 * @license http://opensource.org/licenses/BSD-3-Clause New BSD License
 * @version svn:$Id$
 * @package Lotusphp\Autoloader
 */

/**
 * 自动加载类和函数
 * 
 * 按需加载类,每次只加载用到的类。
 * 
 *     函数库文件不是按需加载!若支持加载函数,则所有定义函数的文件都会加载。
 * 
 * 代码中用到一个类或者函数的时候,不需要使用include/require来包含类库文件或者函数库文件。
 * 
 * 基于Autoloader组件的代码中将不用使用include/require。
 * 
 * Autoloader缓存的是绝对路径,能让Opcode Cache有效缓存文件。
 * 
 *     Autoloader要求类的名字唯一,不在意类文件的路径和文件名。目前不支持命名空间(PHP5.3)
 * 
 * 传统的include/require通常存在以下问题。
 * <ul>
 * <li>目录名和文件名变化引起程序代码变化。</li>
 * <li>Windows和Linux对文件路径的大小写和目录分隔符号的处理不同导致代码在不同平台迁移时出现问题。</li>
 * <li>include_path相对路径的性能低(显著地低)。</li>
 * <li>为了保证不重复包含,使用include_once和require_once导致效率低(不是显著的低)。</li>
 * </ul>
 * @author Jianxiang Qin <TalkativeDoggy@gmail.com> Yi Zhao <zhao5908@gmail.com>
 * @category runtime
 * @package Lotusphp\Autoloader
 * @todo 所有class-file mapping当成一个数据写入storeHandle
 */
class LtAutoloader
{
        /** 
         * @var bool true|false 是否自动加载定义了函数的文件。
         * false 只自动加载定义了class或者interface的文件。
         * true (默认) 自动加载定义了函数的文件。
         */
        public $isLoadFunction = true;
        
        /**
         * @var array 要扫描的文件类型
         * 若该属性设置为array("php","inc","php3"),
         * 则扩展名为"php","inc","php3"的文件会被扫描,
         * 其它扩展名的文件会被忽略
         */
        public $allowFileExtension = array('php', 'inc');
        
        /**
         * @var array 不扫描的目录
         * 若该属性设置为array(".svn", ".setting"),
         * 则所有名为".setting"的目录也会被忽略
         */
        public $skipDirNames = array('.svn', '.git');

        /** @var LtStoreFile 存储句柄默认使用 @link LtStoreFile */
        public $storeHandle;
        
        /** @var array 指定需要自动加载的目录列表 */
        public $autoloadPath;
        
        /** @var bool
     * true 开发模式下  每次都会扫描目录列表
     * false 生产环境下 只扫描一次
     */
        public $devMode = true;
        
        /** @var array 函数名 -> 文件路径  映射 */
        private $functionFileMapping = array();

    /** @var array 类名 -> 文件路径  映射 */
    private $classFileMapping = array();

    /** @var array 定义了函数的文件列表 */
    private $functionFiles = array();

    /** @var LtStoreFile 持久存储句柄,存储文件的get_token_all分析结果/filesize/filehash @link LtStoreFile */
    private $persistentStoreHandle;

    /** @var int store name space id */
    private $storeNameSpaceId;

    /** @var int number of parse error */
    private $parseErrorAmount = 0;

    /** @var int number of library files successfully parsed */
    private $libFileAmount = 0;

        /**
         * 递归扫描指定的目录列表,根据@see LtAutoloader::$isLoadFunction是否加载全部的函数定义文件。
         * 注册自动加载函数,按需加载类文件。
         * @return void
         */
        public function init()
        {
        $this->storeNameSpaceId = sprintf("%u", crc32(serialize($this->autoloadPath)));

        if (true != $this->devMode)
        {
            if ($this->storeHandle instanceof LtStore)
            {
                $this->storeHandle->prefix = 'Lt-Autoloader-' . $this->storeNameSpaceId;
            }
            else
            {
                if (null == $this->storeHandle)
                {
                    $this->storeHandle = new LtStoreFile;
                    $this->storeHandle->prefix = 'Lt-Autoloader-' . $this->storeNameSpaceId;
                    $this->storeHandle->useSerialize = true;
                    $this->storeHandle->init();
                }
                else
                {
                    trigger_error("You passed a value to autoloader::storeHandle, but it is NOT an instance of LtStore");
                }
            }
        }
        else
        {
            $this->storeHandle = new LtStoreMemory;
        }

                // Whether scanning directory
                if ($storedMap = $this->storeHandle->get("map"))
        {
            $this->classFileMapping = $storedMap["classes"];
            $this->functionFiles = $storedMap["functions"];
        }
        else
                {
            $this->setPersistentStoreHandle();
                        $autoloadPath = $this->preparePath($this->autoloadPath);
                        foreach($autoloadPath as $path)
                        {
                                if (is_file($path))
                                {
                                        $this->addFileMap($path);
                                }
                        }
                        $this->scanDirs($autoloadPath);
                        unset($autoloadPath);
                }

                // Whether loading function files
                $this->loadFunctionFiles();
                spl_autoload_register(array($this, "loadClass"));
        }

    protected function setPersistentStoreHandle()
    {
        $this->persistentStoreHandle = new LtStoreFile;
        $this->persistentStoreHandle->prefix = 'Lt-parsed-token-' . $this->storeNameSpaceId;
        $this->persistentStoreHandle->useSerialize = true;
    }

        /**
         * Autoloader扫描项目,若某个php文件中定义了函数,则此文件的绝对路径被缓存,
         * 每次执行LtAutoloader->init()方法时,自动include所有定义了函数的php文件。
     * 因为PHP的Autoload机制是针对Class的.function文件没有办法按需加载
         * @return void
         */
        protected function loadFunctionFiles()
        {
                if ($this->isLoadFunction && count($this->functionFiles))
                {
                        foreach ($this->functionFiles as $functionFile)
                        {
                                include_once($functionFile);
                        }
                }
        }

        /**
         * 被注册的自动加载函数
         * @param string $className
         * @return void 
         */
        protected function loadClass($className)
        {
                if ($filePath = $this->getFilePathByClassName($className))
                {
                        include($filePath);
                }
        }

        /**
         * 将目录分隔符号统一成linux目录分隔符号/
         * @param string $path
         * @return boolean
         */
        protected function convertPath($path)
        {
                $path = str_replace("\\", "/", $path);
                if (!is_readable($path))
                {
                        trigger_error("Directory is not exists/readable: {$path}");
                        return false;
                }
                $path = rtrim(realpath($path), '\\/');
                if (preg_match("/\s/i", $path))
                {
                        trigger_error("Directory contains space/tab/newline is not supported: {$path}");
                        return false;
                }
                return $path;
        }

        /**
         * The string or an Multidimensional array into a one-dimensional array
         * 将字符串和多维数组转换成一维数组
         * @param mixed $paths
         * @return array one-dimensional array
         */
        protected function preparePath($paths)
        {
                $oneDPathArray = array();
                if (!is_array($paths))
                {
                        $paths = array($paths);
                }
                $i = 0;
                while (isset($paths[$i]))
                {
                        if (!is_array($paths[$i]) && $path = $this->convertPath($paths[$i]))
                        {
                                $oneDPathArray[] = $path;
                        }
                        else
                        {
                                foreach($paths[$i] as $v)
                                {
                                        $paths[] = $v;
                                }
                        }
                        $i ++;
                }
        unset($paths);
                return $oneDPathArray;
        }

        /**
         * Using iterative algorithm scanning subdirectories
         * save autoloader filemap
         * 递归扫描目录包含子目录,保存自动加载的文件地图。
         * @param array $dirs one-dimensional
         * @return void
     * @todo in_array换成array_key_exists以提升性能
         */
        protected function scanDirs($dirs)
        {
                $i = 0;
                while (isset($dirs[$i]))
                {
                        $dir = $dirs[$i];
                        $files = scandir($dir);
                        foreach ($files as $file)
                        {
                $currentFile = $dir . DIRECTORY_SEPARATOR . $file;
                if (is_file($currentFile))
                {
                    $this->addFileMap($currentFile);
                }
                else if (is_dir($currentFile))
                {
                    if (in_array($file, array(".", "..")) || in_array($file, $this->skipDirNames))
                    {
                        continue;
                    }
                    else
                    {
                        // if $currentFile is a directory, pass through the next loop.
                        $dirs[] = $currentFile;
                    }
                }
                else
                {
                    trigger_error("$currentFile is not a file or a directory.");
                }
                        } //end foreach
                        $i ++;
                } //end while

        if(0 == $this->parseErrorAmount)
        {
            $this->functionFiles = array_unique(array_values($this->functionFileMapping));
            $map = array("classes" => $this->classFileMapping, "functions" => $this->functionFiles);
            if ($this->storeHandle->get("map"))
            {
                $this->storeHandle->update("map", $map);
            }
            else
            {
                $this->storeHandle->add("map", $map);
            }
        }
        else
        {
            trigger_error($this->parseErrorAmount . " error(s) occoured when scanning and parsing your lib files");
        }
        }

    /**
     * 分析出字符串中的类,接口,函数。 
     * @param string $src
     * @return array
     * @todo 若当前文件包含了直接执行的php语句,或者html,输出警告
     * @todo 若当前文件有语法错误,抛出异常
     */
        protected function parseLibNames($src)
        {
                $libNames = array();
                $tokens = token_get_all($src);
                $level = 0;
                $found = false;
                $name = '';
                foreach ($tokens as $token)
                {
                        if (is_string($token))
                        {
                                if ('{' == $token)
                                {
                                        $level ++;
                                }
                                else if ('}' == $token)
                                {
                                        $level --;
                                }
                        }
                        else
                        {
                                list($id, $text) = $token;
                                if (T_CURLY_OPEN == $id || T_DOLLAR_OPEN_CURLY_BRACES == $id)
                                {
                                        $level ++;
                                }
                                if (0 < $level)
                                {
                                        continue;
                                }
                                switch ($id)
                                {
                                        case T_STRING:
                                                if ($found)
                                                {
                                                        $libNames[strtolower($name)][] = $text;
                                                        $found = false;
                                                }
                                                break;
                                        case T_CLASS:
                                        case T_INTERFACE:
                                        case T_FUNCTION:
                                                $found = true;
                                                $name = $text;
                                                break;
                                }
                        }
                }
                return $libNames;
        }

        /**
         * 保存类名、接口名和对应的文件绝对路径。 
         * @param string $className
         * @param string $file
         * @return boolean
         */
        protected function addClass($className, $file)
        {
                $key = strtolower($className);
                if (isset($this->classFileMapping[$key]))
                {
            $existedClassFile = $this->classFileMapping[$key];
                        trigger_error("duplicate class [$className] found in:\n$existedClassFile\n$file\n, or please clear the cache");
                        return false;
                }
                else
                {
            $this->classFileMapping[$key] = $file;
                        return true;
                }
        }

        /**
         * 保存函数名和对应的文件绝对路径
         * @param string $functionName
         * @param string $file
         * @return boolean
         */
        protected function addFunction($functionName, $file)
        {
                $functionName = strtolower($functionName);
                if (isset($this->functionFileMapping[$functionName]))
                {
                        $existedFunctionFile = $this->functionFileMapping[$functionName];
                        trigger_error("duplicate function [$functionName] found in:\n$existedFunctionFile\n$file\n");
                        return false;
                }
                else
                {
                        $this->functionFileMapping[$functionName] = $file;
                        return true;
                }
        }

        /**
         * 将文件添加到自动加载的FileMap,
         * 添加之前会判断自从上次扫描后有没有修改,若没有修改则无需重复添加,
         * 若修改过,则分析文件内容,根据内容中包含的类、接口,函数添加到FileMap
         * @param string $filePath
         * @return boolean
         */
        protected function addFileMap($filePath)
        {
        if (!in_array(pathinfo($filePath, PATHINFO_EXTENSION), $this->allowFileExtension))
        {//init()会调用这个方法, 不要将这个判断移动到scanDir()中
            return false;
        }
        $fileSize = filesize($filePath);
        $fileHash = md5_file($filePath);

        $savedFileInfo = $this->persistentStoreHandle->get($filePath);
                if (!isset($savedFileInfo['file_size']) || $savedFileInfo['file_size'] != $fileSize || $savedFileInfo['file_hash'] != $fileHash)
                {
            if($libNames = $this->parseLibNames(trim(file_get_contents($filePath))))
            {
                $newFileInfo = array('file_size' => $fileSize, 'file_hash' => $fileHash, 'lib_names' => $libNames);
                if (isset($savedFileInfo['file_size']))
                {
                    $this->persistentStoreHandle->update($filePath, $newFileInfo);
                }
                else
                {
                    $this->persistentStoreHandle->add($filePath, $newFileInfo);
                }
            }
                        else
            {
                $this->parseErrorAmount ++;
            }
                }
        else
        {
            $libNames = $savedFileInfo['lib_names'];
        }

        foreach ($libNames as $libType => $libArray)
        {
            $method = "function" == $libType ? "addFunction" : "addClass";
            foreach ($libArray as $libName)
            {
                if (!$this->$method($libName, $filePath))
                {
                    $this->parseErrorAmount ++;
                }
            }
        }
                return true;
        }

    protected function getFilePathByClassName($className)
    {
        $key = strtolower($className);
        if (isset($this->classFileMapping[$key]))
        {
            return $this->classFileMapping[$key];
        }
        else
        {
            return false;
        }
    }
} 

6、set_include_path 方式

set_include_path(implode(PATH_SEPARATOR, array(get_include_path(), './services', './printers')));
spl_autoload_register();

7、PSR-4: Autoloader

http://www.php-fig.org/psr/psr-4/

 

参考文章

http://www.phpro.org/tutorials/SPL-Autoload.html

https://github.com/qinjx/adv_php_book/blob/master/class_autoload.md

http://php.net/manual/zh/language.oop5.autoload.php

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/1082309.htmlTechArticle关于php中的spl_autoload_register,splautoloadregister 一、自动加载定义 很多开发者写面向对象的应用程序时对每个类的定义建立一个 PHP 源文件。...
성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
PHP와 Python : 다른 패러다임이 설명되었습니다PHP와 Python : 다른 패러다임이 설명되었습니다Apr 18, 2025 am 12:26 AM

PHP는 주로 절차 적 프로그래밍이지만 객체 지향 프로그래밍 (OOP)도 지원합니다. Python은 OOP, 기능 및 절차 프로그래밍을 포함한 다양한 패러다임을 지원합니다. PHP는 웹 개발에 적합하며 Python은 데이터 분석 및 기계 학습과 같은 다양한 응용 프로그램에 적합합니다.

PHP와 Python : 그들의 역사에 깊은 다이빙PHP와 Python : 그들의 역사에 깊은 다이빙Apr 18, 2025 am 12:25 AM

PHP는 1994 년에 시작되었으며 Rasmuslerdorf에 의해 개발되었습니다. 원래 웹 사이트 방문자를 추적하는 데 사용되었으며 점차 서버 측 스크립팅 언어로 진화했으며 웹 개발에 널리 사용되었습니다. Python은 1980 년대 후반 Guidovan Rossum에 의해 개발되었으며 1991 년에 처음 출시되었습니다. 코드 가독성과 단순성을 강조하며 과학 컴퓨팅, 데이터 분석 및 기타 분야에 적합합니다.

PHP와 Python 중에서 선택 : 가이드PHP와 Python 중에서 선택 : 가이드Apr 18, 2025 am 12:24 AM

PHP는 웹 개발 및 빠른 프로토 타이핑에 적합하며 Python은 데이터 과학 및 기계 학습에 적합합니다. 1.PHP는 간단한 구문과 함께 동적 웹 개발에 사용되며 빠른 개발에 적합합니다. 2. Python은 간결한 구문을 가지고 있으며 여러 분야에 적합하며 강력한 라이브러리 생태계가 있습니다.

PHP 및 프레임 워크 : 언어 현대화PHP 및 프레임 워크 : 언어 현대화Apr 18, 2025 am 12:14 AM

PHP는 현대화 프로세스에서 많은 웹 사이트 및 응용 프로그램을 지원하고 프레임 워크를 통해 개발 요구에 적응하기 때문에 여전히 중요합니다. 1.PHP7은 성능을 향상시키고 새로운 기능을 소개합니다. 2. Laravel, Symfony 및 Codeigniter와 같은 현대 프레임 워크는 개발을 단순화하고 코드 품질을 향상시킵니다. 3. 성능 최적화 및 모범 사례는 응용 프로그램 효율성을 더욱 향상시킵니다.

PHP의 영향 : 웹 개발 및 그 이상PHP의 영향 : 웹 개발 및 그 이상Apr 18, 2025 am 12:10 AM

phphassignificallyimpactedwebdevelopmentandextendsbeyondit

스칼라 유형, 반환 유형, 노조 유형 및 무효 유형을 포함한 PHP 유형의 힌트 작업은 어떻게 작동합니까?스칼라 유형, 반환 유형, 노조 유형 및 무효 유형을 포함한 PHP 유형의 힌트 작업은 어떻게 작동합니까?Apr 17, 2025 am 12:25 AM

PHP 유형은 코드 품질과 가독성을 향상시키기위한 프롬프트입니다. 1) 스칼라 유형 팁 : PHP7.0이므로 int, float 등과 같은 기능 매개 변수에 기본 데이터 유형을 지정할 수 있습니다. 2) 반환 유형 프롬프트 : 기능 반환 값 유형의 일관성을 확인하십시오. 3) Union 유형 프롬프트 : PHP8.0이므로 기능 매개 변수 또는 반환 값에 여러 유형을 지정할 수 있습니다. 4) Nullable 유형 프롬프트 : NULL 값을 포함하고 널 값을 반환 할 수있는 기능을 포함 할 수 있습니다.

PHP는 객체 클로닝 (클론 키워드) 및 __clone 마법 방법을 어떻게 처리합니까?PHP는 객체 클로닝 (클론 키워드) 및 __clone 마법 방법을 어떻게 처리합니까?Apr 17, 2025 am 12:24 AM

PHP에서는 클론 키워드를 사용하여 객체 사본을 만들고 \ _ \ _ Clone Magic 메소드를 통해 클로닝 동작을 사용자 정의하십시오. 1. 복제 키워드를 사용하여 얕은 사본을 만들어 객체의 속성을 복제하지만 객체의 속성은 아닙니다. 2. \ _ \ _ 클론 방법은 얕은 복사 문제를 피하기 위해 중첩 된 물체를 깊이 복사 할 수 있습니다. 3. 복제의 순환 참조 및 성능 문제를 피하고 클로닝 작업을 최적화하여 효율성을 향상시키기 위해주의를 기울이십시오.

PHP vs. Python : 사용 사례 및 응용 프로그램PHP vs. Python : 사용 사례 및 응용 프로그램Apr 17, 2025 am 12:23 AM

PHP는 웹 개발 및 컨텐츠 관리 시스템에 적합하며 Python은 데이터 과학, 기계 학습 및 자동화 스크립트에 적합합니다. 1.PHP는 빠르고 확장 가능한 웹 사이트 및 응용 프로그램을 구축하는 데 잘 작동하며 WordPress와 같은 CMS에서 일반적으로 사용됩니다. 2. Python은 Numpy 및 Tensorflow와 같은 풍부한 라이브러리를 통해 데이터 과학 및 기계 학습 분야에서 뛰어난 공연을했습니다.

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를 무료로 생성하십시오.

뜨거운 도구

MinGW - Windows용 미니멀리스트 GNU

MinGW - Windows용 미니멀리스트 GNU

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

DVWA

DVWA

DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는

SecList

SecList

SecLists는 최고의 보안 테스터의 동반자입니다. 보안 평가 시 자주 사용되는 다양한 유형의 목록을 한 곳에 모아 놓은 것입니다. SecLists는 보안 테스터에게 필요할 수 있는 모든 목록을 편리하게 제공하여 보안 테스트를 더욱 효율적이고 생산적으로 만드는 데 도움이 됩니다. 목록 유형에는 사용자 이름, 비밀번호, URL, 퍼징 페이로드, 민감한 데이터 패턴, 웹 셸 등이 포함됩니다. 테스터는 이 저장소를 새로운 테스트 시스템으로 간단히 가져올 수 있으며 필요한 모든 유형의 목록에 액세스할 수 있습니다.

SublimeText3 Mac 버전

SublimeText3 Mac 버전

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

메모장++7.3.1

메모장++7.3.1

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