Symfony2框架学习笔记之HTTP Cache用法详解

本文实例讲述了Symfony2框架HTTP Cache用法。分享给大家供大家参考,具体如下:

富web应用程序的本质意味着它们的动态。无论你的应用程序多么有效率,每个请求比起静态文件来说总会存在很多的耗费。对于大多数web程序来说,这没什么。 Symfony2非常的轻快,无论你做些严重超载的请求,每个请求将会得到很快的回复,而不会对你的服务器造成压力。但是随着你站点的成长,负载将成为一个严重的问题。对每个请求处理应该只被正常执行一次。这就是缓存真正要达成的目标。

站在巨人肩膀上的缓存:

提高一个应用程序执行效率的最有效方法是缓存一个页面的所有输出然后让后续的请求绕开整个应用程序。当然,这对于高动态性的站点来说并不是总是可能的。Symfony2 缓存系统是比较特别的,因为它依赖于在HTTP规范中定义的简单强大的HTTP cache。没有重新发明新的缓存方法,Symfony2 拥抱在web上定义基础交流的标准。一旦你理解了基础的HTTP校验和过期缓存模式,你就会完全掌握了Symfony2的缓存系统。

第一步:一个网关缓存(gateway cache),或者反向代理。是一个坐在你应用程序前面的对立的层。反向代理缓存来自于你应用程序的响应并使用这些缓存响应在某些请求到达你应用程序之前来回复它们。 Symfony2提供了自己的反向代理,也可以使用其它任何的反向代理。

第二步:HTTP缓存 (HTTP cache)头用于和网关缓存以及任何其位于客户和你的应用程序之间的其它缓存交流。Symfony2 提供了和缓存头交互的预设行为和强大接口。

第三步:HTTP 超时和校验时用于决定一个缓存内容是否新鲜和陈旧的两种模式。

第四步:ESI(Edge Side Includes)允许HTTP缓存被用于独立缓存页面片段(甚至是嵌套片段)。使用ESI,你甚至可以缓存一个完整的页面60分钟。但一个嵌入式边栏缓存只有5分钟。

使用网关缓存

当使用HTTP缓存时,缓存是跟你的应用程序完全分离的,它位于你的请求客户端和应用程序之间。该缓存的工作就是从客户端接收请求并把它们传递回你的应用程序。同时它也将接收从你的应用程序返回的响应并把它转给客户端。可以说它是你的应用程序和请求客户端之间请求-响应交互的中间人。

按照这个思路,缓存会保存被认为是“可缓存的”每一个响应回复。当同样的请求再次传来时,该缓存会把自己缓存的响应直接回复给请求客户端,而完全忽略你的应用程序。这种类型的缓存就是HTTP网关缓存。目前有很多这类缓存,比如Varnish,Squid in reverse proxy mode和Symfony2 反向代理等。

缓存类型

一个网关缓存不是缓存的唯一类型。事实上,有三种不同类型的缓存会截获并使用你的应用程序发出的HTTP缓存头。它们是:

浏览器缓存(Browser caches):浏览器拥有自己的本地缓存,这对你单击"前一步"或者查看图片和其它网络资产时起到了主要作用。

代理缓存(Proxy caches):一个代理缓存是一个多人位于一人之后的共享的缓存。它们大多是一些大公司或者ISP安装用来减少延迟和网络阻塞的。

网关缓存(Gateway caches):像一个代理,也是一个共享缓存但是是位于服务器端的。一般是网络管理员安装它们,它使得网站更具可伸缩性,可靠性和高效性。网关缓存有时候被称为反向代理缓存,代理缓存,更或者是HTTP加速器。

Symfony2 反向代理

Symfony2拥有一个用PHP编写的反向代理(也叫做网关缓存)。开启它后,来自你应用程序的可缓存的响应回复将会开始被立刻缓存。安装它相也当容易。每一个新的Symfony2应用程序都有一个预配置缓存内核(AppCache)包含了一个默认的AppKernel。该缓存内核就是个反向代理。要开启缓存,修改前端控制器代码使用缓存内核:

loadClassCache(); //使用AppCache包裹默认的AppKernel $kernel = new AppCache($kernel); $kernel->handle(Request::createFromGlobale())->send();

缓存内核会立刻扮演一个反向代理的角色,缓存来自你应用程序的回复把它们发回给请求客户端。

注意,该缓存内核有一个特别的getLog()方法返回一个能够表示在缓存层发生了什么的字符串。

可以在开发环境中来调试和校验你的缓存策略。

getLog());

AppCache 对象是一个合理的默认配置,当然你也可以通过重写getOptions()方法来设置可选项对它进行调优。

false,'default_ttl' => 0,'private_headers' => array('Authorization','Cookie'),'allow_reload' => false,'allow_revalidate' => false,'stale_while_revalidate' => 2,'stale_if_error' => 60,); } }

注意,这里无论怎么重写getOptions()方法,其中debug选项将被包裹的AppKernel的debug值自动设置。

default_ttl: 当没有显式的刷新信息在回复中提供时,一个缓冲实体应该被认为是新鲜的时间秒数。显式的设置Cache-Control 或者 Expires 头会覆盖这个参数值。默认值为0。 private_headers:请求头组,它在回复上触发"private" Cache-Control 行为,无论回复是通过Cache-Control 指令显式的声明是public还是private 。默认为Authorization和Cookie。 allow_reload: 指定是否允许客户端通过在请求中指定Cache-Control的"no-cache"指令来强迫缓存重新加载。设置它为true时符合RFC2616规范。默认值为false。 allow_revalidate:指定是否允许客户端通过在请求中指定Cache-Control的"max-age=0"指令来强迫缓存重新校验。设置它为true时符合RFC2616规范。默认值为false。 stale_while_revalidate:用于指定一个默认秒数(间隔是秒因为回复TTL精度是1秒),在期间缓存还在后台进行重新校验时可以立刻返回一个陈旧的回复(默认是2);该设置会被stale-while-revalidate HTTP Cache-Control扩展重写(RFC 5861)。 stale_if_error: 指定一个默认秒数(间隔是秒)在这期间缓存可以提供一个陈旧的回复当遇到一个错误时。默认值为60。该设置会被stale-if-error HTTP Cache-Contorl 扩展重写(RFC5861)

如果debug设置为true,Symfony2 会自动添加一个X-Symfony-Cache 头到回复保存着关于缓存点击和丢失的信息。

从一个反向代理到另一个的转换:

Symfony2反向代理是一个在开发你的站点或者部署你的站点到一个共享主机而你无法安装任何除PHP代码以外的东西时的非常有用的工具。但是因为使用PHP编写,它不能跟用C写成的反向代理那样快速。这就是为什么我们推荐使用Varnish或者Squid到你的运营服务器上的原因。好消息是从一个代理服务器到另外一个替换很容易,简单的不用你修改任何程序代码。你可以开始时使用Symfony2的反向代理等到了阻塞增加时升级到Varnish。

注意:Symfony2 反向代理执行效率独立于应用程序的复杂性。因为应用程序核心仅仅在请求需要被转发到它时才被启动。

HTTP缓存说明:

为了发挥可用缓存层的优势,你的应用程序必须能传达它的哪个回复可以被缓存,什么时候/怎样 缓存会变成陈旧的规则。这些是通过在回复(response)上设置HTTP 缓存头来实现的。

记住,"HTTP"只不过是一种web客户端和服务器之间交流的简单文本语言。当我们说HTTP 缓存时,我们说的是它允许客户端和服务器交换信息相关的缓存。

HTTP指定了4个Response缓存头,我们需要关注一下:

其中最重要的也是万能的头是Cache-Control头,它其实是一个各种缓存信息的集合。

Cache-Control Header

Cache-Control头是唯一的一个其内部包含了各种各样的关于一个response是否可以被缓存的信息。每条信息之间用逗号隔开。

Symfony 提供一个Cache-Control头的抽象,使它的创建更加可控。

setPublic(); $response->setPrivate(); // 设置private或者shared 的最大年龄 age $response->setMaxAge(600); $response->setSharedMaxAge(600); // 设置一个自定义的Cache-Control 指令 $response->headers->addCacheControlDirective('must-revalidate',true);

公共vs私有 Response

网关缓存和代理缓存都被认为是“共享”缓存,因为它们缓存的内容是被多用户共享的。如果一个特定用户的回复曾被错误的存储到共享缓存中,它以后可能被返回给无数的不用用户。想象一下,如果你的账户信息被缓存然后返回给每一个后来请求他们自己账户页面的用户。要处理这种情况,每个回复可能都要设置时public还是private。

public 说明给回复可能被private和共享的缓存保存。 private 说明所有的或者部分的回复信息时给一个单独用户的,所以不能缓存到共享缓存中。

Symfony 谨慎地默认每个回复为private。 要使用共享缓存的优点(比如Symfony2反向代理),回复必须被显式的设置为public。

安全方法:

HTTP缓存仅仅为安全方法工作(比如GET和HEAD)。要安全意味着当它为某个请求服务时从来不会改变服务器上应用程序的状态。(当然你可以写日志信息,缓存数据等)。这里有两个很合理的后果(consequences):

当你的应用程序回复一个GET或者HEAD请求时,你绝对不会改变你应用程序的状态。即使你不用网关缓存,代理缓存的存在意味着任何GET和HEAD请求可能会或者可能不会真的达到你的服务器。

不要期望PUT,POST或者DELETE方法被缓存。这些方法被使用意味着你应用程序状态的改变。缓存它们将阻止某种请求访问或者改变你的应用程序。

缓存规则和默认设置

HTTP 1.1 默认情况下允许缓存任何事情除非有一个显式的Cache-Control头。实践中,大多数缓存当请求有cookie,一个授权头,使用一个非安全的方法(比如PUT,POST,DELETE)或者当请求有一个重定向代码时,不会进行任何缓存活动。

当开发者没有做任何设置时,Symfony2 会自动按照下面的规则设置一个合理的比较保守的Cache-Control头:

如果没有缓存头被定义(Cache-Control,Expires,ETag 或者Last-Modified),Cache-Control被设置为no-cache,意味着该response将不会被缓存。

如果Cache-Control 为空(但是有另一个缓存头存在),它的值被设置为private,must-revalidate;

如果至少一个Cache-Control指令被设置,并且没有'public'或者‘private'指令被显式的添加,Symfony2 会自动添加一个private指令(除去s-maxage 被设置的情况)。

HTTP过期和校验

HTTP规范定义了两个缓存模型: 过期模型,你只需要通过包含一个Cache-Control和/或者一个Expires头来指定一个Response应该多长时间被考虑“新鲜”问题。缓存理解过期将不再让相同的请求回复,直到缓存的版本达到它过期时间成为“stale"陈旧。

校验模型,当页面时真正的动态页面时(他们的展现经常变化),校验模型就经常需要了。这种模型,缓存存储response,但是要求服务对每个请求是否缓存response依然进行校验。

应用程序使用唯一的response 标示符(ETag 头) 和/或者 时间戳(Last-Modified 头)来检查页面自从被缓存后是否放生了变化。

这两个模型的目标是通过依靠一个缓存存储并返回"新鲜" response,使得应用程序从不生成相同的response两次。

过期:

过期模型是在这两个模型中是更加有效和简单明确的模型,它应该在任何时候都有被使用的可能。当一个response使用一过期方式被缓存,缓存将存储response并为请求直接返回它而不去访问应用程序,直到它过期。

过期模型可以被熟练的使用一两个,几乎相同的,HTTP头:比如 Expires或cache - control。

过期和Expires 头

根据HTTP规范,Expires头字段提供一个日期/时间,过了这个日期或时间后它的response就被认为是陈旧的了。Expires头可以被Response的setExpires()方法设置。它要求一个DateTime实例作为输入参数。

modify('+600 seconds'); $response->setExpires($date);

生成的HTTP头的结果如下:

注意,因为规范的需要setExprise()方法会自动把日期转换为GMT时区。

我们注意到在HTTP规范1.1版之前,源服务不需要发送一个Date头。 因此缓存(比如浏览器)可能需要依靠它本地的始终来评估Expires头,造成计算生命周期时时钟偏差。 Expires头的另一个限制是规范规定:"HTTP/1.1服务不应该发送Expires日期未来超过一年。"

过期和Cache-Control 头

因为Expires头的限制,大多时候,你应该采用Cache-Control头来替代它。回想一下,Cache-Control头是用来指定多个不同缓存指令的。对于过期来说,有两个指令,max-age 和 s-maxage。第一个被所有的缓存使用,然而第二个仅仅被用于共享缓存。

setMaxAge(600); // 同上,但是只用于共享缓存。 $response->setSharedMaxAge(600); Cache-Control头将使用如下格式(它可能还有其它指令): Cache-Control: max-age=600,s-maxage=600

校验:

一旦底层数据发生变化需要立刻对缓存资源进行更新时,过期模型就显得力不从心了。在过期模型下,应用程序不会被要求返回更新的response直到缓存最后过期变为陈旧内容以后。

校验模型解决了这个问题。在校验模型下,缓存持续保存response。不同的是,对每一个请求request,缓存都询问应用程序缓存的response是否依然有效。如果缓存仍然有效,你的应用程序应该返回一个304状态码和一个空内容。这告诉缓存它可以为请求用户返回它缓存的response。

在这个模型下,你主要节省了带宽因为描述不会发送两次到相同的客户端(而是发送一个304回复代替)。但是,如果你仔细设计你的应用程序,你可能能忍受304 response需要的最小数据并节省CPU。

304状态码意味着没有修改。它很重要因为它没有包含整整的被请求内容,而只是一个轻量级的导向集,它告诉缓存它应该使用它现在保存的版本回复请求。跟过期类似,也有两个不同的HTTP头可以被用来实现校验模型: ETag和Last-Modifed

校验和ETag头

ETag头是一个字符串(也叫"entity-tag")它是目标资源一个表现的唯一标识。它完全由你的应用程序来生成和设置。 比如,如果 /about 资源被缓存保存时取决于日期和你应用程序的返回内容。一个ETag像一个手印,被用来快速的比较一个资源的两个不同版本是否等效。 像手印,同一个资源的所有表示形式中每个ETag必须是唯一的。让我们来简单实现一个生成ETag使用md5加密的回复内容作为内容:

render('MyBundle:Main:index.html.twig'); $response->setETag(md5($response->getContent())); $response->isNotModified($this->getRequest()); return $response; }

Response::isNotModified()方法把和Request一起发送的ETag与Response上的ETag进行比较。如果两个匹配,方法自动设置Response状态码为304。

这个算法非常简单也非常通用,但是你需要在能计算ETag之前创建一个完整的Response,校验模型是次优选择。换句话说,它节省了带宽,单没有节省CPU利用。

Symfony2还通过向setETag()方法传入true作为第二个参数,来支持弱ETag。

校验和Last-Modified 头

Last-Modified头是校验模型的第二种形式。根据HTTP规范,”Last-Modified 头字段指定日期和时间,在这个时间源服务器相信该表现是最后被修改版。“ 换句话说,应用程序决定基于自动缓存内容被缓存后是否被更新过来判断缓存的内容是否要被更新过。举个例子,你可以使用最新更新日期为所有需要计算资源表现的对象作为Last-Modified头的值:

getUdateAt()); $authorDate = new \DateTime($author->getUpdateAt());\ $date = $authorDate>$articleDate ? $authorDate : $articleDate; $response->setLastModified($date); $response->isNotModified($this->getRequest()); return $response; }

Response::isNotModified() 方法比较请求Request中的If-Modified-Since头和Response中的Last-Modified 头。如果他们相等,Response会被设置一个304状态码。

注意,If-Modified-since 请求头等于最终发送到客户端特定资源Last-Modified头。这就是如何客户端和服务端相互交流决定资源自从它被缓存后是否被更新。

使用校验优化你的代码:

任何缓存策略的主要目的都是减轻应用程序的加载。换句话说,你的应用程序做的越少来返回304 response,越好。Response::isNotModified()方法通过暴露一个简单有效的模式做到了。

setETag($article->computeETag()); $response->setLastModified($article->getPublishedAt()); //为给定的Request检查Response没有被修改 if($response->isNotModified($this->getRequest())){ //立刻返回304 Response return $response; }else{ //做一些更多的工作-比如获取更多的数据 $comment=//... //或者用你已经开启的$response渲染一个模版 return $this->render('MyBundle:MyController:article.html.twig',array('article'=>$article,'comments' =>$comments),$response ); } }

当Response没有被修改后,isNotModified()自动设置response的状态码为304,移除response的内容,移除一些不需要为304存在的头。

不同的回复响应:

到目前为止,我们已经假设了每个URI只有一个目标资源的表示。默认情况下,HTTP缓存通过使用URI的资源作为缓存键被执行。如果两个人请求同一个可缓存资源的URI,第二个用户将获取缓存版本。有时候这些不够,不同版本的用一个URI需要被按照一个或者多个请求头的值来被缓存。举个例子,如果当客户端支持你压缩页面时,任何给定的URI都有两种表示:一个是客户端支持压缩时,一个是不支持时的表示。这时候请求头的Accept-Encoding值将决定使用哪个。

在这种情况下,我们需要回复的特定URI缓存一个压缩版本和一个非压缩版本,基于请求的Accept-Encoding值返回它们。这是通过Vary Response头,Vary是一个不同头用逗号分隔,它的值触发请求资源的不同表示。

注意,这个特别的Vary头,将基于URI和Accept-Encoding和User-Agent 请求头为每个资源的不同版本进行缓存。

Response对象提供一个干净的接口来管理Vary 头:

setVary('Accept-Encoding'); // 设置多个vary头 $response->setVary(array('Accept-Encoding','User-Agent'));

setVary()方法需要一个头名字或者一个头名字数组对应不同的response。

过期和校验:

你当然可以在同一个Response中同时使用校验和过期。因为过期胜过校验,你可以轻易的从它们两个中根据好处做出选择。换句话说,通过同时使用过期和校验,你可以指示缓存服务于缓存的内容,同时后台间隔检查来调查内容是否依然合法。

更多Response方法:

Response类提供了许多和缓存相关的方法。下面是主要的一些:

expire(); // 强迫response返回一个适合 304 的没有内容的response $response->setNotModified();

另外,跟缓存最相关的HTTP头可以被通过一个单独的方法setCache()设置。

setCache(array( 'etag' => $etag,'last_modified' => $date,'max_age' => 10,'s_maxage' => 10,'public' => true,// 'private' => true,));

使用ESI(Edge Side Includes)

网关缓存是一个提高你网站执行效率的很好的途径。但是它们有一个限制:只能缓存整个页面。如果你不想缓存整个页面或者页面的某一部分很动态,你就没那么幸运了。

幸运的是,Symfony2为这些情况提供一个解决方案,基于ESI技术。它允许页面指定的部分和主页比起来有一个不同的缓存策略。

ESI规范描述标签你可以嵌入到你的页面来和网关缓存交流。Symfony2中只实现了一个标签,include,因为这是唯一一个能在Akami上下文之外使用的标签。

Some content More content

从这个例子中注意到每个ESI标签有一个全限定URL。一个ESI标签表示可以通过一个给定的URL获取的一个页面片段。

当请求被处理时,网关缓存从它的缓存或者从背后的应用程序中请求回复获取整个页面。换句话说,网关缓存既从缓存中获取包含的页面片段也会再次从背后的应用程序中获取回复请求的页面片段。当所有的ESI标签被解析后,网关缓存合并每一个ESI内容到一个主页并返回最后的内容到客户端。所有的这一切都透明的发生在网关缓存级(在你的程序外)。你将看到,如果你选择ESI标签,Symfony2让这包含它们的这一过程几乎不费劲。

在Symfony2中使用ESI

首先,使用ESI需要确认在你的应用程序配置中已经打开。

YAML格式:

XML格式:

PHP代码格式:

loadFromExtension('framework',array( // ... 'esi' => array('enabled' => true),));

现在假设我们有一个页面时相对静态的,除了一个新闻自动收报机在内容的底部。使用ESI,我们可以缓存新闻自动收报机独立于页面其它部分。

render('MyBundle:MyController:index.html.twig'); $response->setSharedMaxAge(600); return $response; }

在该示例中,我们给全页面缓存周期为10分钟。接下来,通过嵌入一个action让新闻ticker包含到模板中。这是通过render帮助来实现的。因为嵌入的内容来自其它页面,Symfony2使用一个标准的render帮助来配置ESI标签:

Twig格式:

PHP格式:

render('...:news',array(),array('standalone' => true)) ?>

通过把standalone设置为true,告诉Symfony2这个action应该被渲染为一个ESI标签。

你可能想知道为什么要使用一个helper方法来代替直接写ESI标签。这是因为使用helper让你的应用程序工作即使没有网关缓存被安装。让我们来看看它是怎样工作的。

当standalone为false时(也是默认值),Symfony2在发送response到客户端之前合并包含的页面内容到一个主页。

但是当standalone为true时,并且如果Symfony2发现它跟支持ESI的网关缓存对话时,它生成一个ESI include标签。

如果没有网关缓存或者网关缓存不支持ESI,Symfony2将只合并包含的标签页面内容到一个主要的像它在standalone为false时所做的一样。

嵌入的action现在可以指定自己的缓存规则了,完全独立于主页。

setShareMaxAge(60); }

使用ESI,整个页面缓存将被保持600秒有效,但是新闻组建缓存将只持续60秒。

ESI的一个必备条件是嵌入的action可以通过一个URL被访问,这样网关缓存才可以独立于页面其它部分获取它。当然,一个action不能被通过一个URL访问除非有一个路由指向它。Symfony2 通过一个通用的路由和controller负责这个。

为了ESI包含标签能正常的工作,你必须定义_internal 路由:

YAML格式:

XML格式:

PHP代码格式:

addCollection($loader->import('@FrameworkBundle/Resources/config/routing/internal.xml','/_internal')); return $collection;

因为路由允许所有的action通过一个URL被访问,你可以通过使用Symfony2防火墙(允许访问你的反向代理的IP范围)内容保护它。

缓存策略的一大优势是你可以让你的应用程序根据动态的需要同时又尽量的减少触及应用程序。

一旦你开始使用ESI,请记住一定使用s-maxage指令代替max-age。因为浏览器只接受聚合的资源,它不知道子组件,所以它会按照max-age指令缓存整个页面。这是你不希望它做的。

render helper支持的两外两个有用选项: alt:用作ESI标签的alt属性,当src找不到时,它允许你指定一个替代URL。 ignore_errors:如果设置为true,一个onerror属性将被添加到ESI,并且属性值设置为continue,在一个失败事件中,网关缓存将只默默的移除ESI标签。

缓存失效:

“计算机科学中有两大难题:缓存失效和命名事物”---Phil Karlton

你永远都不需要失效缓存数据,因为失效早已在HTTP缓存模型中被考虑到了。如果你使用校验,你永远都不需要通过定义校验任何事情;如果你使用过期并失效某个资源,它意味着你设置一个未来的过期日期。因为在任何类型的反向代理中失效都是一个顶级规范,如果你不担心失效,你可以在不改变任何应用程序代码的情况下在反向代理间切换。

其实,所有的反向代理都提供了清除缓存数据的方式,但是你需要尽量的避免使用它们。最标准的清除给定URL的缓存的方式是通过指定请求的HTTP方法为PURGE 来进行。

下面是如何配置Symfony2的反向代理支持PURGE HTTP方法:

getMethod()) { return parent::invalidate($request); } $response = new Response(); if (!$this->getStore()->purge($request->getUri())) { $response->setStatusCode(404,'Not purged'); } else { $response->setStatusCode(200,'Purged'); } return $response; } }

注意,你必须保护你的PURGE HTTP方法以避免随便一个人使用某些方法清除你的缓存数据。

总结:

Symfony2旨在遵循一条被证明了的道路规则:HTTP。 缓存也不例外。掌握Symfony2缓存系统意味着熟悉HTTP缓存模式和有效的使用它们。

这就意味着,你不能只依赖于symfony2文档和代码示例,你必须了解有关HTTP缓存和网关缓存的更宽阔的知识,比如Varnish。

希望本文所述对大家基于Symfony框架的PHP程序设计有所帮助。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


文章浏览阅读8.4k次,点赞8次,收藏7次。SourceCodester Online Tours & Travels Management System pay.php sql injectionLine 16 of pay.php invokes a SQL query built using unvalidated input. This call could allow an attacker to modify the statement’s meaning or to execute arbitrary SQL commands.SQL
文章浏览阅读3.4k次,点赞46次,收藏51次。本文为大家介绍在windwos系统搭建typecho博客+cpolar内网穿透工具将博客发布到公共网络环境,实现远程也可以访问和操作。_windows搭建typecho
文章浏览阅读1.1k次。- php是最优秀, 最原生的模板语言, 替代语法,让php更加的优雅的与html生活在一起 -->请放心, 最终生成的,或者说用户最终看到的,仍然是一个html文档, php代码中的内容不会被泄漏的。-- 将php与html代码混编的时候,大括号很容易造成配对错误,最好杜绝它 -->php标签内部代码由php.exe解释, php标签之外的代码原样输出,仍由web服务器解析。-- 所以php的流程控制语句, 都提供了替代语法,用冒号代替大括号 -->php echo '百变鹏仔'?_利用php将静态页面修改为动态页面
文章浏览阅读1.1k次,点赞18次,收藏15次。整理K8s网络相关笔记博文内容涉及 Linux network namespace 认知以及彼此通信Demo,实际中的应用理解不足小伙伴帮忙指正不必太纠结于当下,也不必太忧虑未来,当你经历过一些事情的时候,眼前的风景已经和从前不一样了。——村上春树。_linux network namespace 多端通信 模式认知
文章浏览阅读1.2k次,点赞22次,收藏19次。此网络模型提供了一个逻辑二层(L2)网络,该网络封装在跨 Kubernetes 集群节点的现有三层(L3)网络拓扑上。使用此模型,可以为容器提供一个隔离的 L2 网络,而无需分发路由。封装网络带来了少量的处理开销以及由于覆盖封装生成 IP header 造成的 IP 包大小增加。封装信息由 Kubernetes worker 之间的 UDP 端口分发,交换如何访问 MAC 地址的网络控制平面信息。此类网络模型中常用的封装是 VXLAN、Internet 协议安全性 (IPSec) 和 IP-in-IP。_k8s网络组件对比
文章浏览阅读1.1k次,点赞14次,收藏19次。当我们谈论网络安全时,我们正在讨论的是保护我们的在线空间,这是我们所有人的共享责任。网络安全涉及保护我们的信息,防止被未经授权的人访问、披露、破坏或修改。
文章浏览阅读1.3w次,点赞3次,收藏7次。尽管您可以通过 ping 命令解析出网站的 IP 地址,但是可能在浏览器中访问时仍然遇到问题,这可能是因为浏览器使用的 DNS 解析结果不同于 ping 命令使用的解析结果。可能是因为您的网络或设备上设置了防火墙,阻止了对特定网站的访问。有些国家或组织可能会对特定的域名进行屏蔽,从而阻止访问相关网站。如果您的网络使用代理服务器进行访问控制,可能会由于代理服务器的配置问题导致无法访问某些网站。即使您的网络和设备一切正常,目标网站本身可能也存在问题,例如服务器故障、维护或过载,导致无法访问。_能ping通打不开网页
文章浏览阅读839次,点赞22次,收藏19次。本系统带文档lw万字以上文末可领取本课题的JAVA源码参考。
文章浏览阅读2.1k次,点赞31次,收藏22次。基于微信小程序奶茶点餐外卖系统设计与实现(PHP后台+Mysql)可行性分析毕设源代码毕业设计,数据安全和系统稳定性以及团队能力和资源配备方面都具备较好的条件。因此,该项目的可行性较高。:黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;微信小程序作为一种快捷、方便的移动应用形式,成为很多用户点餐外卖的首选。项目的界面和功能都可以定制,包安装运行!项目配有对应开发文档、开题报告、任务书、PPT、论文模版等。
文章浏览阅读1.8k次,点赞52次,收藏38次。本文主要通过对系统的前台系统和后台管理系统进行了功能性需求分析,对系统的安全性和可扩展性进行了非功能性需求分析。在详细的需求分析的基础上,根据系统的功能设计确定了数据库结构,实现完整的代码编写。Lucky+Baby母婴用品网站使用 Dreamweaver、HBuilder代码编辑器、Apache服务器等开发工具,完成了系统的主要模块的页面设计和功能实现。本文展示了首页页面的实现效果图,并通过代码和页面介绍了用户注册功能、商品搜索功能、生成订单和查看我的订单功能、在线付款功能功能的实现过程。
文章浏览阅读1.5k次,点赞45次,收藏40次。本设计主要实现集人性化、高效率、便捷等优点于一身的人事信息管理系统,完成首页、系统用户、通知公告、部门信息、员工薪资、考勤签到、员工请假、招聘信息、应聘信息等功能模块。
文章浏览阅读1k次。该错误通常出现在数据库读取结果集数据时,比如当我们写好SQL语句从数据库读取数据时,本身应该返回结果集,再给结果集中读取数据。解决思路:这种错误一般是因为echo后面输出了一个数组导致的,或者是数组作为字符串进行拼接运算时导致的。该错误直译为:警告:mysqli_fetch_assoc函数期望参数1是mysqli的结果集,但是给了一个布尔值。这种错误是PHP解析器在解析时遇到了语法错误,直译为:解析错误:语法错误,意料之外的...该错误直译为:提示:未定义的索引:username。_array to string conversion in
文章浏览阅读2.7w次。解决http请求报错context deadline exceeded (Client.Timeout exceeded while awaiting headers)_context deadline exceeded (client.timeout exceeded while awaiting headers)
文章浏览阅读1.3k次,点赞26次,收藏24次。复杂网络是一种由大量相互连接的元素(节点或顶点)组成的网络结构,这些连接通常是非常复杂和动态的。这些网络可以在各种领域中发现,包括社交网络、生物学系统、信息技术和交通系统等。_代理建模
文章浏览阅读2.6k次,点赞76次,收藏71次。epoll详解,事件模型,ET/LT模式,并通过三个示例进行代码实现。
文章浏览阅读3.3k次。罗拉ROLA-IP是一家来自纽约的代理IP提供商,由李嘉诚先生投资建设,韩国人工智能、自动驾驶、虚拟现实方面的领军企业World IT Show投资入股,由美国纽约大学IT管理教授团队研究开发,进入中国市场6年多,全世界设有多个分子公司。接下来,我们要检查代理和防火墙的设置,因为在绝大多数情况下,它们是导致这个错误的原因,尤其是当用户使用免费代理时。对网站的访问受阻实际上是一个非常常见的错误,它既可能是由于物理原因(硬件问题)造成的,也可能是由于软件错误引起的。检查代理设置,并确保其正确配置。_无法访问此网站,检查代理服务器和防火墙
文章浏览阅读1.1k次,点赞14次,收藏20次。本系统带文档lw万字以上文末可领取本课题的JAVA源码参考。_php洗车服务预约管理系统php源码
文章浏览阅读1.1k次。桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。同时,对于桶中元素的排序,选择何种比较排序算法对于性能的影响至关重要。
文章浏览阅读936次,点赞22次,收藏17次。本系统带文档lw万字以上文末可领取本课题的JAVA源码参考。
文章浏览阅读822次,点赞15次,收藏14次。在整个设计过程中,要确定可能的具体解决方案,以实现每一个小的最终目标,对于每一个小目标,我们首先必须了解一些相关的需求分析信息。除了以上作品下面是2023-2024年最新100套计算机专业原创的毕业设计源码+数据库,是近期作品,如果你的题目刚好在下面可以文末领取java源码参考。springboot基于springboot的在线考试系统。springboot基于springboot的商城购物系统。springboot基于微信小程序的智慧校园设计与实现。springboot基于用户的协同过滤算法的话题推荐。