php中命名空间namespace用法介绍
现在说这个,感觉有点过时了,但是感觉用namespace的人还是不多,估计还是因为不习惯吧。
class把一个一个function组织起来,namespace可以理解成把一个一个class,function等有序的组织起来。个人觉得,namespace的主要优势有
第一,可以更好的管理代码
第二,文件一多,可以避免class,function的重名
第三,代码可读性增强了
1,定义namespace
namespace userCenter; //php代码 namespace userCenter\register; //php代码 namespace userCenter\login { //php代码 }
命名空间不能嵌套或在同一代码处声明多次(只有最后一次会被识别)。但是,你能在同一个文件中定义多个命名空间化的代码,比较合适的做法是每个文件定义一个命名空间(可以是相同命名空间)。
2,调用namespace
\userCenter\register; //绝对调用
userCenter\login; //相对调用
use userCenter\register; //引用空间
use userCenter\register as reg; //引用空间并加别名
3,实例说明
login.class.php
<?php namespace userCenter; function check_username(){ echo "login OK<br>"; } class login{ public function save(){ echo "login had saved<br>"; } } ?> regist.class.php <?php namespace userCenter\regist { function check_username() { echo "regist OK<br>"; } class regist{ public function save(){ echo "regist had saved<br>"; } } } ?>
test.php
<?php require "login.class.php"; require "regist.class.php"; use userCenter\regist; //使用use调用空间 use userCenter\regist as reg; //as定义别名 echo \userCenter\check_username(); //绝对调用 $login = new \userCenter\login(); echo $login->save(); echo regist\check_username(); //相对调用 echo reg\check_username(); //别名调用 $regist = new reg\regist(); echo $regist->save();
使用use,比绝对调用要好一点,好比给class,function等加了一个前缀,这样看起来就比较清楚了
今天赶上了123System OPenVZ VPS全场半价的机会,购入了一台512MB内存、双核3.49Ghz Xeon E3-1270 V3 CPU的套餐,这是第一次使用123system的产品,整体印象非常不错,就目前而言速度也是杠杠哒,便手动配置起了最新版的Tengine和PHP 5.6.8。在编译完成之后我决定以PHP -FPM的方式来运行PHP,下面是从各处收集到并且重新整理的一些关于FPM使用的技巧,记录一下方便自己与一些平时接触到这方面工作的朋友吧!
1、安装完之后,对php-conf的修改:
修改用户组:
user = www-data
group = www-data
如果www-data用户不存在,那么执行linux命令先添加www-data用户
groupadd www-data
useradd -g www-data www-data
部分参数解析:
pid = run/php-fpm.pid
#pid设置,默认在安装目录中的var/run/php-fpm.pid,建议开启
error_log = log/php-fpm.log
#错误日志,默认在安装目录中的var/log/php-fpm.log
log_level = notice
#错误级别. 可用级别为: alert(必须立即处理), error(错误情况), warning(警告情况), notice(一般重要信息), debug(调试信息). 默认: notice.
emergency_restart_threshold = 60
emergency_restart_interval = 60s
#表示在emergency_restart_interval所设值内出现SIGSEGV或者SIGBUS错误的php-cgi进程数如果超过 emergency_restart_threshold个,php-fpm就会优雅重启。这两个选项一般保持默认值。
process_control_timeout = 0
#设置子进程接受主进程复用信号的超时时间. 可用单位: s(秒), m(分), h(小时), 或者 d(天) 默认单位: s(秒). 默认值: 0.
daemonize = yes
#后台执行fpm,默认值为yes,如果为了调试可以改为no。在FPM中,可以使用不同的设置来运行多个进程池。 这些设置可以针对每个进程池单独设置。
listen = 127.0.0.1:9000
#fpm监听端口,即nginx中php处理的地址,一般默认值即可。可用格式为: 'ip:port', 'port', '/path/to/unix/socket'. 每个进程池都需要设置.
listen.backlog = -1
#backlog数,-1表示无限制,由操作系统决定,此行注释掉就行。backlog含义参考:http://www.3gyou.cc/?p=41
listen.allowed_clients = 127.0.0.1
#允许访问FastCGI进程的IP,设置any为不限制IP,如果要设置其他主机的nginx也能访问这台FPM进程,listen处要设置成本地可被访问的IP。默认值是any。每个地址是用逗号分隔. 如果没有设置或者为空,则允许任何服务器请求连接
2、对Nginx.conf的fastcgi部分修改:
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
3、PHP-FPM启动相关参数
#测试php-fpm配置
/usr/local/php/sbin/php-fpm -t
/usr/local/php/sbin/php-fpm -c /usr/local/php/etc/php.ini -y /usr/local/php/etc/php-fpm.conf -t
#启动php-fpm
/usr/local/php/sbin/php-fpm
/usr/local/php/sbin/php-fpm -c /usr/local/php/etc/php.ini -y /usr/local/php/etc/php-fpm.conf
#关闭php-fpm
kill -INT `cat /usr/local/php/var/run/php-fpm.pid`
#重启php-fpm
kill -USR2 `cat /usr/local/php/var/run/php-fpm.pid`
4、Nginx的开启与关闭
结束进程:fuser -k 80/tcp
启动Nginx:sudo /usr/local/nginx/nginx
基本设置
创建一个简单的Doctrine实体类:
// src/Acme/DemoBundle/Entity/Document.php namespace Acme\DemoBundle\Entity; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Validator\Constraints as Assert; /** * @ORM\Entity */ class Document { /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ public $id; /** * @ORM\Column(type="string", length=255) * @Assert\NotBlank */ public $name; /** * @ORM\Column(type="string", length=255, nullable=true) */ public $path; public function getAbsolutePath() { return null === $this->path ? null : $this->getUploadRootDir().'/'.$this->path; } public function getWebPath() { return null === $this->path ? null : $this->getUploadDir().'/'.$this->path; } protected function getUploadRootDir() { // the absolute directory path where uploaded // documents should be saved return __DIR__.'/../../../../web/'.$this->getUploadDir(); } protected function getUploadDir() { // get rid of the __DIR__ so it doesn't screw up // when displaying uploaded doc/image in the view. return 'uploads/documents'; } }
该document实体有一个名称与文件相关联。这个path属性存储一个文件的相对路径并且在数据库中存储。这个getAbsolutePath()会返回一个绝对路径,getWebPath()会返回一个web路径,用于模板加入上传文件链接。
如果你还没有这样做的话,你应该阅读http://symfony.com/doc/current/reference/forms/types/file.html首先了解基本的上传过程。
如果您使用注释来验证规则(如本例所示),请确保你启用了注释验证(见http://symfony.com/doc/current/book/validation.html#book-validation-configuration)。
在处理一个实际的文件上传时,使用一个“虚拟”的file字段。例如,如果你在controller中直接构建一个form,他可能是这样的:
public function uploadAction() { // ... $form = $this->createFormBuilder($document) ->add('name') ->add('file') ->getForm(); // ... } 下一步,创建file这个属性到你的Document类中并且添加一些验证规则: use Symfony\Component\HttpFoundation\File\UploadedFile; // ... class Document { /** * @Assert\File(maxSize="6000000") */ private $file; /** * Sets file. * * @param UploadedFile $file */ public function setFile(UploadedFile $file = null) { $this->file = $file; } /** * Get file. * * @return UploadedFile */ public function getFile() { return $this->file; } } annotations Annotations // src/Acme/DemoBundle/Entity/Document.php namespace Acme\DemoBundle\Entity; // ... use Symfony\Component\Validator\Constraints as Assert; class Document { /** * @Assert\File(maxSize="6000000") */ private $file; // ... }
当你使用File约束,symfony会自动猜测表单字段输入的是一个文件上传。这就是当你创建表单(->add(‘file’))时,为什么没有在表单明确设置为文件上传的原因。
下面的控制器,告诉您如何处理全部过程:
// ... use Acme\DemoBundle\Entity\Document; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; use Symfony\Component\HttpFoundation\Request; // ... /** * @Template() */ public function uploadAction(Request $request) { $document = new Document(); $form = $this->createFormBuilder($document) ->add('name') ->add('file') ->getForm(); $form->handleRequest($request); if ($form->isValid()) { $em = $this->getDoctrine()->getManager(); $em->persist($document); $em->flush(); return $this->redirect($this->generateUrl(...)); } return array('form' => $form->createView()); }
以前的controller当提交name自动的存储Document实体,但是他不会做任何关于文件的事情并且path属性也将是空白。
处理文件上传一个简单的方法就是在entity持久化之前设置相应的path属性。在某一时刻处理文件上传时,要调用Document实体类一个upload()方法给path赋值。
if ($form->isValid()) { $em = $this->getDoctrine()->getManager(); $document->upload(); $em->persist($document); $em->flush(); return $this->redirect(...); } 这个upload()方法利用UploadedFile对象,是它提交后返回file字段: public function upload() { // the file property can be empty if the field is not required // 该file属性为空这个属性就不需要了 if (null === $this->getFile()) { return; } // use the original file name here but you should // sanitize it at least to avoid any security issues // 这里你应该使用原文件名但是应该至少审核它避免一些安全问题 // move takes the target directory and then the // target filename to move to // 将目标文件移动到目标目录 $this->getFile()->move( $this->getUploadRootDir(), $this->getFile()->getClientOriginalName() ); // set the path property to the filename where you've saved the file // 设置path属性为你保存文件的文件名 $this->path = $this->getFile()->getClientOriginalName(); // clean up the file property as you won't need it anymore // 清理你不需要的file属性 $this->file = null; } 使用生命周期回调 生命周期回调是一种有限的技术,他有一些缺点。如果你想移除Document::getUploadRootDir()方法里的写死的编码__DIR__,最好的方法是开始使用Doctrine listeners。在哪里你将能够注入内核参数,如kernel.root_dir来建立绝对路径。 这种原理工作,他有一个缺陷:也就是说当entity持久化时会有什么问题呢?答:该文件已经转移到了它的最终位置,实体类下的path属性不能够正确的实体化。 (如果entity有持久化问题或者文件不能够移动,什么事情也没有发生)为了避免这些问题,你应该改变这种实现方式以便数据库操作和自动删除文件: /** * @ORM\Entity * @ORM\HasLifecycleCallbacks */ class Document { }
接下来,利用这些回调函数重构Document类:
use Symfony\Component\HttpFoundation\File\UploadedFile; /** * @ORM\Entity * @ORM\HasLifecycleCallbacks */ class Document { private $temp; /** * Sets file. * * @param UploadedFile $file */ public function setFile(UploadedFile $file = null) { $this->file = $file; // check if we have an old image path // 检查如果我们有一个旧的图片路径 if (isset($this->path)) { // store the old name to delete after the update $this->temp = $this->path; $this->path = null; } else { $this->path = 'initial'; } } /** * @ORM\PrePersist() * @ORM\PreUpdate() */ public function preUpload() { if (null !== $this->getFile()) { // do whatever you want to generate a unique name // 去生成一个唯一的名称 $filename = sha1(uniqid(mt_rand(), true)); $this->path = $filename.'.'.$this->getFile()->guessExtension(); } } /** * @ORM\PostPersist() * @ORM\PostUpdate() */ public function upload() { if (null === $this->getFile()) { return; } // if there is an error when moving the file, an exception will // be automatically thrown by move(). This will properly prevent // the entity from being persisted to the database on error //当移动文件发生错误,一个异常move()会自动抛出异常。 //这将阻止实体持久化数据库发生错误。 $this->getFile()->move($this->getUploadRootDir(), $this->path); // check if we have an old image if (isset($this->temp)) { // delete the old image unlink($this->getUploadRootDir().'/'.$this->temp); // clear the temp image path $this->temp = null; } $this->file = null; } /** * @ORM\PostRemove() */ public function removeUpload() { $file = $this->getAbsolutePath(); if ($file) { unlink($file); } } }
如果更改你的entity是由Doctrine event listener 或event subscriber处理,这个 preUpdate()回调函数必须通知Doctrine关于正在做的改变。有关preUpdate事件限制的完整参考请查看 http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#preupdate
现在这个类做了你需要的一切:他会在entity持久化之前生成一个唯一的文件名,持久化之后,移动文件,删除文件。
现在移动文件是entity自动完成,这个$document->upload()就应该从controller中移除了:
if ($form->isValid()) { $em = $this->getDoctrine()->getManager(); $em->persist($document); $em->flush(); return $this->redirect(...); }
这个@ORM\PrePersist()和@ORM\PostPersist()事件回调:一个是在entity持久化到数据库之前触发,一个是在entity持久化到数据库之后触发。另一方面, @ORM\PreUpdate() 和 @ORM\PostUpdate()事件回调时当实体更新时触发。
当改变entity字段后进行持久化操作时,PreUpdate和PostUpdate回调才会被触发。这意味着,默认情况下,你只改变了$file属性,这些事件不会被触发,因为这个属性它自己不会持久化到Doctrine。有一个解决方法,就是创建一个updated字段把它持久化到Doctrine,并当文件改变时手动调整它。
使用ID作为文件名
如果要使用ID作为文件名,实现略有不同,您需要保存path属性为文件扩展名,而不是实际的文件名:
use Symfony\Component\HttpFoundation\File\UploadedFile; /** * @ORM\Entity * @ORM\HasLifecycleCallbacks */ class Document { private $temp; /** * Sets file. * * @param UploadedFile $file */ public function setFile(UploadedFile $file = null) { $this->file = $file; // check if we have an old image path if (is_file($this->getAbsolutePath())) { // store the old name to delete after the update $this->temp = $this->getAbsolutePath(); } else { $this->path = 'initial'; } } /** * @ORM\PrePersist() * @ORM\PreUpdate() */ public function preUpload() { if (null !== $this->getFile()) { $this->path = $this->getFile()->guessExtension(); } } /** * @ORM\PostPersist() * @ORM\PostUpdate() */ public function upload() { if (null === $this->getFile()) { return; } // check if we have an old image if (isset($this->temp)) { // delete the old image unlink($this->temp); // clear the temp image path $this->temp = null; } // you must throw an exception here if the file cannot be moved // so that the entity is not persisted to the database // which the UploadedFile move() method does $this->getFile()->move( $this->getUploadRootDir(), $this->id.'.'.$this->getFile()->guessExtension() ); $this->setFile(null); } /** * @ORM\PreRemove() */ public function storeFilenameForRemove() { $this->temp = $this->getAbsolutePath(); } /** * @ORM\PostRemove() */ public function removeUpload() { if (isset($this->temp)) { unlink($this->temp); } } public function getAbsolutePath() { return null === $this->path ? null : $this->getUploadRootDir().'/'.$this->id.'.'.$this->path; } }
你会注意到,在这种情况下,你需要做一点工作,以删除该文件。在数据删除之前,你必须保存文件路径(因为它依赖于ID)。然后,一旦对象已经完全从数据库中删除,你就可以安全的删除文件(在数据删除之后)。
众所周知,mysql有slow query log,根据慢查询日志,我们可以知道那些sql语句有性能问题。作为mysql的好搭档,php也有这样的功能。如果你使用php-fpm来管理php的话,你可以通过如下选项开启。
PHP 5.3.3 之前设置如下:
<value name=”request_slowlog_timeout”>5s</value>
<value name=”slowlog”>logs/php-fpm-slowlog.log</value>
PHP 5.3.3 之后设置以下如下:
request_slowlog_timeout = 5s
slowlog = /usr/local/php/log/php-fpm-slowlog.log
说明:
request_slowlog_timeout是脚本超过多长时间 就可以记录到日志文件
slowlog 是日志文件的路径
开启后,如果有脚本执行超过指定的时间,就会在指定的日志文件中写入类似如下的信息:
[19-Dec-2013 16:54:49] [pool www] pid 18575
script_filename = /home/admin/web/htdocs/sandbox_canglong/test/tt.php
[0x0000000003a00dc8] curl_exec() /home/admin/web/htdocs/sandbox_canglong/test/tt.php:2
[0x0000000003a00cd0] exfilter_curl_get() /home/admin/web/htdocs/sandbox_canglong/test/tt.php:6
日志说明:
script_filename 是入口文件
curl_exec() : 说明是执行这个方法的时候超过执行时间的。
exfilter_curl_get() :说明调用curl_exec()的方法是exfilter_curl_get() 。
每行冒号后面的数字是行号。
开启后,在错误日志文件中也有相关记录。如下:
[19-Dec-2013 15:55:37] WARNING: [pool www] child 18575, script ‘/home/admin/web/htdocs/sandbox_canglong/test/tt.php’ (request: “GET /test/tt.php”) executing too slow (1.006222 sec), logging
[19-Dec-2013 15:55:37] NOTICE: child 18575 stopped for tracing
[19-Dec-2013 15:55:37] NOTICE: about to trace 18575
[19-Dec-2013 15:55:37] NOTICE: finished trace of 18575
SplFixedArray主要是处理数组相关的主要功能,与普通php array不同的是,它是固定长度的,且以数字为键名的数组,优势就是比普通的数组处理更快。
看看我本机的Benchmark测试:
ini_set('memory_limit','12800M');
for($size = 10000; $size < 10000000; $size *= 4) {
echo PHP_EOL . "Testing size: $size" . PHP_EOL;
for($s = microtime(true), $container = Array(), $i = 0; $i < $size; $i++) $container[$i] = NULL;
echo "Array(): " . (microtime(true) - $s) . PHP_EOL;
for($s = microtime(true), $container = new SplFixedArray($size), $i = 0; $i < $size; $i++) $container[$i] = NULL;
echo "SplArray(): " . (microtime(true) - $s) . PHP_EOL;
}
结果如下:
Testing size: 10000
Array(): 0.004000186920166
SplArray(): 0.0019998550415039
Testing size: 40000
Array(): 0.017001152038574
SplArray(): 0.0090007781982422
Testing size: 160000
Array(): 0.050002098083496
SplArray(): 0.046003103256226
Testing size: 640000
Array(): 0.19701099395752
SplArray(): 0.16700983047485
Testing size: 2560000
Array(): 0.75704312324524
SplArray(): 0.67303895950317
通常情况下SplFixedArray要比php array快上20%~30%,所以如果你是处理巨大数量的固定长度数组,还是强烈建议使用。
SplFixedArray类摘要如下:
SplFixedArray implements Iterator , ArrayAccess , Countable {
/* 方法 */
public __construct ([ int $size = 0 ] )
public int count ( void )
public mixed current ( void )
public static SplFixedArray fromArray ( array $array [, bool $save_indexes = true ] )
public int getSize ( void )
public int key ( void )
public void next ( void )
public bool offsetExists ( int $index )
public mixed offsetGet ( int $index )
public void offsetSet ( int $index , mixed $newval )
public void offsetUnset ( int $index )
public void rewind ( void )
public int setSize ( int $size )
public array toArray ( void )
public bool valid ( void )
public void __wakeup ( void )
}
使用SplFixedArray:
$arr = new SplFixedArray(4);
$arr[0] = 'php';
$arr[1] = 1;
$arr[3] = 'python';
//遍历, $arr[2] 为null
foreach($arr as $v) {
echo $v . PHP_EOL;
}
//获取数组长度
echo $arr->getSize(); //4
//增加数组长度
$arr->setSize(5);
$arr[4] = 'new one';
//捕获异常
try{
echo $arr[10];
} catch (RuntimeException $e) {
echo $e->getMessage();
}
SplFixedArray和Array的性能测试
PHP文档专门说明:
The SplFixedArray class provides the main functionalities of array. The main differences between a SplFixedArray and a normal PHP array is that the SplFixedArray is of fixed length and allows only integers within the range as indexes. The advantage is that it allows a faster array implementation.
所以在处理大型的、以数字为索引的数组时,应该用SplFixedArray来代替普通Array。
下面是测试代码:
<?php
function pr() {
$params = func_get_args();
$env = php_sapi_name();
if ("cli" == $env) {
foreach ($params as $key => $value) {
echo $value;
}
} else {
foreach ($params as $key => $value) {
echo "<pre>";
print_r($value);
echo "</pre>";
}
}
} // 用来打印输出结果
<?php
require dirname(__FILE__)."/function.php";
for ($size=1000; $size<=50000000; $size*=2) {
pr(PHP_EOL . "Testing size: $size" . PHP_EOL);
for($s = microtime(true), $container = Array(), $i = 0; $i < $size; $i++) {
$container[$i] = NULL;
}
pr( "Array(): " . (microtime(true) - $s) . PHP_EOL);
for($s = microtime(true), $container = new SplFixedArray($size), $i = 0; $i < $size; $i++) {
$container[$i] = NULL;
}
pr("SplArray(): " . (microtime(true) - $s) . PHP_EOL);
}
但是在我的测试机器上,这段代码出现了非常诡异的结果:
暂时想不出来是什么原因:难道是因为虚拟机内存太小,导致最后的SplFixedArray插入时需要不断GC才导致时间太长?
相关文章
- 这篇文章主要介绍了解决IDEA占用C盘空间过大的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-22
- 这篇文章主要给大家介绍了关于Swift中命名空间的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-30
- 这篇文章主要介绍了c# 如何使用 My 命名空间,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...2020-12-08
- 这篇文章主要介绍了C# 命名空间(Namespace)的相关知识,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以参考下...2020-11-03
- 今天小编就为大家分享一篇关于C++与namespace有关的两个编译错误的讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧...2020-04-25
- 这篇文章主要介绍了Redis swap空间的使用示例,帮助大家更好的理解和学习使用Redis数据库,感兴趣的朋友可以了解下...2021-03-25
- namespace即“命名空间”,也称“名称空间” 、”名字空间”。接下来通过本文给大家介绍JavaScript中命名空间namespace模式的相关知识,非常不错,具有参考借鉴价值,感兴趣的朋友一起学习吧...2016-06-24
- 这篇文章主要介绍了Redis开启键空间通知实现超时通知的步骤,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-01-15
- PHP的命名空间(namespace)是php5.3之后才有的之前学习php所以没有这个东西了,最近用到了php命名空间了,下面我们一起来看看命名空间namespace用法 现在说这个,感觉有...2016-11-25
- 这篇文章主要介绍了Oracle如何设置表空间数据文件大小,文中讲解非常细致,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-22
- .net的命名空间类库的简单介绍,需要的朋友可以参考一下...2020-06-25
- 今天小编在这里就来给美图秀秀的这一款软件的使用者们来说一下制作QQ空间MM签名的教程,各位想知道具体制作步骤的使用者们,那么下面就快来跟着小编一起看一下吧。 ...2016-09-14
- 当一个项目变得大型之后,我们会引入很多的库,这么一来两个库很可能会定义List、Tree、Node同名的类,编译器要是不考虑这情况的话,程序员调用时就会出现冲突问题。C++提供了名称空间工具,以更好的控制名称的作用域,本文就来谈谈C++ 名称空间,需要的朋友可以参考一下...2021-09-24
- 这篇文章主要介绍了Java中XML Namespace 命名空间,XML命名空间是由国际化资源标识符 (IRI) 标识的 XML 元素和属性集合,该集合通常称作 XML“词汇”,对XML Namespace 命名空间相关知识感兴趣的朋友一起看看吧...2021-08-14
- 集合是一些有共同特征的独立数据项组成的,通过集合,我们可以可以使用相同的调用代码来处理一个集合的所有元素,而不用单独处理每一个单独的项...2021-09-22
- 小米手机云空间不足怎么办?使用小米云空间存储照片,视频等,最近发现空间不够用了,估计是视频存的太多了,该怎么办呢?今天和大家分享一下解决小米云空间不足的详细教程,需要的朋友可以参考下...2016-07-04
- 这篇文章主要介绍了C#命名空间与java包的区别,较为详细的分析了C#命名空间与java包的相同点与不同点,非常具有实用价值,需要的朋友可以参考下...2020-06-25
- php有namespace或类似的东西的。对于发布类库框架,或者构建大的程序来说是很重要的。可以避免类名和函数名冲突,又不用像Pear里那样把类名弄得老长。当初php5的测试版曾...2016-11-25
- 这篇文章主要介绍了C++编程中的命名空间基本知识讲解,包括对C++11中内联命名空间新特性的介绍,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了解决ASP.NET MVC 重命名(命名空间)而导致错误的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25