Home > Article > Backend Development > What is Symfoy2 (transfer), symfoy2_PHP tutorial
本文转自:http://www.cnblogs.com/Seekr/archive/2012/06/15/2550894.html
Symfoy2 是什么?
PHP世界里又一广受关注的web MVC框架? Fabien Potencier 却不这么说!
Fabien Potencier这样定义Symfoy2 是个什么东西:
首先,Symfony2 是一个独立,松散的,有组织严密的PHP组件集合,它可以为你解决一些web开发中遇到的一般性问题。
其次,基于这些组件,Symfoy2 也可以作为一个独立的web框架使用。
那么Symfony2 是一个MVC框架吗?
Fabien Potencier 说Symfony2从来没有把自己定义为一个MVC框架!
那它是什么? Fabien Potencier 我们从来不关心MVC模式,关心的只有各个关注点的分离(separation of concerns)。
但是Symfony2 还是提供了部分的MVC模式的实现:比如Controller部分,View部分却没有Mode部分不过你可以通过和它紧密继承的ORM(Doctrine2和Propel)实现。
从这个角度看Symfony的确也没有逃出web MVC框架的圈子啊!!!
Fabien Potencier 又说Symfony2从来就没有想靠这些ORM来使自己成为另一个MVC的追随者,我们的目标更远大!
告诉你吧, Symfony2 是一个HTTP框架或者说是一个Request/Response 框架。我们紧盯的目标不是MVC模式,而是HTTP协议,我们是更低级的更基础的框架。
我们为什么要这么说呢? 有根据的!
近几年随着web的发展,有时候你只需要创建一组REST API,所有的逻辑都放到浏览器端,服务器端只提供数据就是一种web了。不信你看 backbone.js !
再说了,MVC模式只不过是Web 应用程序的其中一种实现方式罢了。
剥去所有框架模式的皮,你看看那个web程序不是处理一个接收到的Request然后返回一个Response啊?
我们Symfony2 抓住的就是web程序的根本! 再说我们众多的HTTP流媒体有哪个会选择使用MVC呢?
总之,我们Symfony2比MVC更靠近根本,我们更底层,更通用!!!
说起Symfony2,Fabien Potencier说我们有着更加远大的目标,怎么解释呢?
Symfony2 将继续专注于Pack技术的研究和创新!我们相信她会继续推动web的向前发展。
先看看Symfony2 中我们已经包含的创新吧!
从Bundles,HTTP 缓存,分布式,依赖注入,模板引擎,声明式配置,资产管理,稳定的API到web分析器等等一系列技术都对web的发展起到了巨大的推动作用。
“ 要知道一个独立的框架永远不可能成为PHP世界里的一个标准,所以Symfony2 在探寻另外一条路!”
“ 共享无处不在。”
“ 我们不能重复制造轮子。”
因此,我们紧密的集成了Monolog,Composer,Doctrine,Propel,Assetic,Twig,Swiftmailer等伟大产品。
更重要的是我们想跟大家分享我们的工作!
所以,我们最终选择了走组件(components)化这条路!
我们将为一切web项目提供建筑模块,无论是个人项目还是商业项目,更或者是开源项目!
据说在Symfony2 的代码中可能会有标志为@api的类或者方法,它意味着一个方法从名字到参数以及返回值都不会因为Symfony2发展版本而变化,所以,如果
你的项目只使用了这些,那么你就不用担心Symfony2的版本升级问题。
看看Symfony2 现在拥有的组件吧:
DependencyInjection
EventDispatcher
HttpFoundation
DomCrawler
ClassLoader
CssSelector
HttpKernel
BrowserKit
Templating
Translation
Serializer
Validator
Security
Routing
Console
Process
Config
Finder
Locale
Yaml
Form
Fabien 简单介绍了几个bundle:
1. ClassLoader:
实现了PSR-o 标准(自动加载具有命名空间的类,适用于PHP5.3以上)的自动加载器,同时它也能按照PEAR命名规则加载类。它非常灵活可以基于子命名空间在不同的目录中查询要加载的类。你甚至可以为一个命名空间指定多个目录。
<span> 1</span> <span>require_once</span> __DIR__.'/src/Symfony/Component/ClassLoader/UniversalClassLoader.php'<span>; </span><span> 2</span> <span> 3</span> <span>use</span><span> Symfony\Component\ClassLoader\UniversalClassLoader; </span><span> 4</span> <span> 5</span> <span>$loader</span> = <span>new</span><span> UniversalClassLoader(); </span><span> 6</span> <span>$loader</span>->registerNamespaces(<span>array</span><span>( </span><span> 7</span> 'Symfony' => <span>array</span>(__DIR__.'/src', __DIR__.'/symfony/src'), <span> 8</span> 'Doctrine\\Common' => __DIR__.'/vendor/doctrine-common/lib', <span> 9</span> 'Doctrine\\DBAL' => __DIR__.'/vendor/doctrine-dbal/lib', <span>10</span> 'Doctrine' => __DIR__.'/vendor/doctrine/lib', <span>11</span> 'Monolog' => __DIR__.'/vendor/monolog/src', <span>12</span> <span>)); </span><span>13</span> <span>$loader</span>->registerPrefixes(<span>array</span><span>( </span><span>14</span> 'Twig_' => __DIR__.'/vendor/twig/lib', <span>15</span> <span>)); </span><span>16</span> <span>$loader</span>->register();
如果你想获取更加高的执行效率,可以选择使用APC缓存版Universal类加载器。
2.Console 命令行工具
在创建web应用程序时使用命令行工具很方便,你可以想如下代码一样创建自己的命令行工具:
<span> 1</span> <span>use</span><span> Symfony\Component\Console\Application; </span><span> 2</span> <span>use</span><span> Symfony\Component\Console\Input\InputInterface; </span><span> 3</span> <span>use</span><span> Symfony\Component\Console\Input\InputArgument; </span><span> 4</span> <span>use</span><span> Symfony\Component\Console\Input\InputOption; </span><span> 5</span> <span>use</span><span> Symfony\Component\Console\Output\OutputInterface; </span><span> 6</span> <span> 7</span> <span>$console</span> = <span>new</span><span> Application(); </span><span> 8</span> <span>$console</span> <span> 9</span> ->register('ls'<span>) </span><span>10</span> ->setDefinition(<span>array</span><span>( </span><span>11</span> <span>new</span> InputArgument('dir', InputArgument::REQUIRED, 'Directory name'), <span>12</span> <span> )) </span><span>13</span> ->setDescription('Displays the files in the given directory'<span>) </span><span>14</span> ->setCode(<span>function</span> (InputInterface <span>$input</span>, OutputInterface <span>$output</span><span>) { </span><span>15</span> <span>$dir</span> = <span>$input</span>->getArgument('dir'<span>); </span><span>16</span> <span>17</span> <span>$output</span>->writeln(<span>sprintf</span>('Dir listing for <info>%s</info>', <span>$dir</span><span>)); </span><span>18</span> <span> }) </span><span>19</span> <span>; </span><span>20</span> <span>$console</span>->run();
3.YAML 一种现在很流行的配置格式。
<span>use</span><span> Symfony\Component\Yaml\Yaml; </span><span>$array</span> = Yaml::parse(<span>$file</span><span>); </span><span>print</span> Yaml::dump(<span>$array</span>);
4. Finder 优秀文件资源的操作接口。
<span> 1</span> <span>use</span><span> Symfony\Component\Finder\Finder; </span><span> 2</span> <span> 3</span> <span>$finder</span> = <span>new</span><span> Finder(); </span><span> 4</span> <span> 5</span> <span>$iterator</span> = <span>$finder</span> <span> 6</span> -><span>files() </span><span> 7</span> ->name('*.php'<span>) </span><span> 8</span> ->depth(0<span>) </span><span> 9</span> ->size('>= 1K'<span>) </span><span>10</span> -><span>in(__DIR__); </span><span>11</span> <span>12</span> <span>foreach</span> (<span>$iterator</span> <span>as</span> <span>$file</span><span>) { </span><span>13</span> <span>print</span> <span>$file</span>->getRealpath()."\n"<span>; </span><span>14</span> }
你甚至可以用它获取远程服务器文件系统中的资源,比如获取Amazon S3上的文件:
<span>1</span> <span>$s3</span> = <span>new</span> \Zend_Service_Amazon_S3(<span>$key</span>, <span>$secret</span><span>); </span><span>2</span> <span>$s3</span>->registerStreamWrapper("s3"<span>); </span><span>3</span> <span>4</span> <span>$finder</span> = <span>new</span><span> Finder(); </span><span>5</span> <span>$finder</span>->name('photos*')->size('< 100K')-><span>date</span>('since 1 hour ago'<span>); </span><span>6</span> <span>foreach</span> (<span>$finder</span>->in('s3://bucket-name') <span>as</span> <span>$file</span><span>) { </span><span>7</span> <span>print</span> <span>$file</span>->getFilename()."\n"<span>; </span><span>8</span> }
5.Process 进程组件,你可以用来在一个外部进程中执行命令!下面例子是执行一个简单的目录列表命令并返回结果:
<span> 1</span> <span>use</span><span> Symfony\Component\Process\Process; </span><span> 2</span> <span> 3</span> <span>$process</span> = <span>new</span> Process('ls -lsa'<span>); </span><span> 4</span> <span>$process</span>->setTimeout(3600<span>); </span><span> 5</span> <span>$process</span>-><span>run(); </span><span> 6</span> <span>if</span> (!<span>$process</span>-><span>isSuccessful()) { </span><span> 7</span> <span>throw</span> <span>new</span> RuntimeException(<span>$process</span>-><span>getErrorOutput()); </span><span> 8</span> <span>} </span><span> 9</span> <span>10</span> <span>print</span> <span>$process</span>->getOutput();
如果你想监控执行过程,你可以给run方法传入一个匿名方法:
<span> 1</span> <span>use</span><span> Symfony\Component\Process\Process; </span><span> 2</span> <span> 3</span> <span>$process</span> = <span>new</span> Process('ls -lsa'<span>); </span><span> 4</span> <span>$process</span>->run(<span>function</span> (<span>$type</span>, <span>$buffer</span><span>) { </span><span> 5</span> <span>if</span> ('err' === <span>$type</span><span>) { </span><span> 6</span> <span>echo</span> 'ERR > '.<span>$buffer</span><span>; </span><span> 7</span> } <span>else</span><span> { </span><span> 8</span> <span>echo</span> 'OUT > '.<span>$buffer</span><span>; </span><span> 9</span> <span> } </span><span>10</span> });
6.DomCrawler jQuery的php版本!你可以用它导航定位HTML的DOM结构或者XML文档。
<span>1</span> <span>use</span><span> Symfony\Component\DomCrawler\Crawler; </span><span>2</span> <span>3</span> <span>$crawler</span> = <span>new</span><span> Crawler(); </span><span>4</span> <span>$crawler</span>->addContent('<html><body><p>Hello World!</p></body></html>'<span>); </span><span>5</span> <span>6</span> <span>print</span> <span>$crawler</span>->filterXPath('descendant-or-self::body/p')->text();
7.CssSelector 我们经常用XPath来访问Dom结构,其实用Css 选择器更加容易,这个组件就是把Css选择器转为XPath等效的东西。
<span>1</span> <span>use</span><span> Symfony\Component\CssSelector\CssSelector; </span><span>2</span> <span>3</span> <span>print</span> CssSelector::toXPath('div.item > h4 > a');
所以你可以使用CssSelector 和DomCrawler来替代XPath:
<span>1</span> <span>use</span><span> Symfony\Component\DomCrawler\Crawler; </span><span>2</span> <span>3</span> <span>$crawler</span> = <span>new</span><span> Crawler(); </span><span>4</span> <span>$crawler</span>->addContent('<html><body><p>Hello World!</p></body></html>'<span>); </span><span>5</span> <span>6</span> <span>print</span> <span>$crawler</span>->filter('body > p')->text();
8.HttpFoundation
该组件只是在PHP的相关web内容上面增加了一个面向对象层,包括Request,Response,Uploaded files,Cookies,Sessions...
<span>1</span> <span>use</span><span> Symfony\Component\HttpFoundation\Request; </span><span>2</span> <span>use</span><span> Symfony\Component\HttpFoundation\Response; </span><span>3</span> <span>4</span> <span>$request</span> = Request::<span>createFromGlobals(); </span><span>5</span> <span>echo</span> <span>$request</span>->getPathInfo();
你用它可以很容易的创建自己的Request 和 Response:
<span>1</span> <span>$request</span> = Request::create('/?foo=bar', 'GET'<span>); </span><span>2</span> <span>echo</span> <span>$request</span>-><span>getPathInfo(); </span><span>3</span> <span>4</span> <span>5</span> <span>$response</span> = <span>new</span> Response('Not Found', 404, <span>array</span>('Content-Type' => 'text/plain'<span>)); </span><span>6</span> <span>$response</span>->send();
9.Routing
路由组件和Request对象是相互配合着把Request转换为Response。
<span> 1</span> <span>use</span><span> Symfony\Component\HttpFoundation\Request; </span><span> 2</span> <span>use</span><span> Symfony\Component\Routing\Matcher\UrlMatcher; </span><span> 3</span> <span>use</span><span> Symfony\Component\Routing\RequestContext; </span><span> 4</span> <span>use</span><span> Symfony\Component\Routing\RouteCollection; </span><span> 5</span> <span>use</span><span> Symfony\Component\Routing\Route; </span><span> 6</span> <span> 7</span> <span>$routes</span> = <span>new</span><span> RouteCollection(); </span><span> 8</span> <span>$routes</span>->add('hello', <span>new</span> Route('/hello', <span>array</span>('controller' => 'foo'<span>))); </span><span> 9</span> <span>10</span> <span>$context</span> = <span>new</span><span> RequestContext(); </span><span>11</span> <span>12</span> <span>//</span><span> this is optional and can be done without a Request instance</span> <span>13</span> <span>$context</span>->fromRequest(Request::<span>createFromGlobals()); </span><span>14</span> <span>15</span> <span>$matcher</span> = <span>new</span> UrlMatcher(<span>$routes</span>, <span>$context</span><span>); </span><span>16</span> <span>17</span> <span>$parameters</span> = <span>$matcher</span>->match('/hello');
10.EventDispatcher
<span> 1</span> <span>use</span><span> Symfony\Component\EventDispatcher\EventDispatcher; </span><span> 2</span> <span>use</span><span> Symfony\Component\EventDispatcher\Event; </span><span> 3</span> <span> 4</span> <span>$dispatcher</span> = <span>new</span><span> EventDispatcher(); </span><span> 5</span> <span> 6</span> <span>$dispatcher</span>->addListener('event_name', <span>function</span> (Event <span>$event</span><span>) { </span><span> 7</span> <span>//</span><span> ...</span> <span> 8</span> <span>}); </span><span> 9</span> <span>10</span> <span>$dispatcher</span>->dispatch('event_name');
11.DependencyInjection
<span>use</span><span> Symfony\Component\DependencyInjection\ContainerBuilder; </span><span>use</span><span> Symfony\Component\DependencyInjection\Reference; </span><span>$sc</span> = <span>new</span><span> ContainerBuilder(); </span><span>$sc</span> ->register('foo', '%foo.class%'<span>) </span>->addArgument(<span>new</span> Reference('bar'<span>)) ; </span><span>$sc</span>->setParameter('foo.class', 'Foo'<span>); </span><span>$sc</span>->get('foo');
12.HttpKernel
Http 内核组件提供了HTTP协议中最有活力的部分,以下面接口的形式定义展示,它也是Symfony2框架的核心。
<span> 1</span> <span>interface</span><span> HttpKernelInterface </span><span> 2</span> <span>{ </span><span> 3</span> <span>/*</span><span>* </span><span> 4</span> <span> * Handles a Request to convert it to a Response. </span><span> 5</span> <span> * </span><span> 6</span> <span> * @param Request $request A Request instance </span><span> 7</span> <span> * </span><span> 8</span> <span> * @return Response A Response instance </span><span> 9</span> <span>*/</span> <span>10</span> <span>function</span> handle(Request <span>$request</span>, <span>$type</span> = self::MASTER_REQUEST, <span>$catch</span> = <span>true</span><span>); </span><span>11</span> }
它接受一个Request输入并返回一个Response输出。 只要遵循这个接口规定,你就能使用Symfony2中所有的精彩内容。
下面使用Symfony2 组件来创建一个简单的框架:
<span> 1</span> <span>$routes</span> = <span>new</span><span> RouteCollection(); </span><span> 2</span> <span>$routes</span>->add('hello', <span>new</span> Route('/hello', <span>array</span>('_controller' => <span> 3</span> <span>function</span> (Request <span>$request</span><span>) { </span><span> 4</span> <span>return</span> <span>new</span> Response(<span>sprintf</span>("Hello %s", <span>$request</span>->get('name'<span>))); </span><span> 5</span> <span> } </span><span> 6</span> <span>))); </span><span> 7</span> <span> 8</span> <span>$request</span> = Request::<span>createFromGlobals(); </span><span> 9</span> <span>10</span> <span>$context</span> = <span>new</span><span> RequestContext(); </span><span>11</span> <span>$context</span>->fromRequest(<span>$request</span><span>); </span><span>12</span> <span>13</span> <span>$matcher</span> = <span>new</span> UrlMatcher(<span>$routes</span>, <span>$context</span><span>); </span><span>14</span> <span>15</span> <span>$dispatcher</span> = <span>new</span><span> EventDispatcher(); </span><span>16</span> <span>$dispatcher</span>->addSubscriber(<span>new</span> RouterListener(<span>$matcher</span><span>)); </span><span>17</span> <span>18</span> <span>$resolver</span> = <span>new</span><span> ControllerResolver(); </span><span>19</span> <span>20</span> <span>$kernel</span> = <span>new</span> HttpKernel(<span>$dispatcher</span>, <span>$resolver</span><span>); </span><span>21</span> <span>22</span> <span>$kernel</span>->handle(<span>$request</span>)->send();
ok, 这就是框架了!
如果想添加一个HTTP反向代理以获取HTTP caching和ESI(Edge Side Includes)带来的好处,那么这样做!
<span>1</span> <span>$kernel</span> = <span>new</span> HttpKernel(<span>$dispatcher</span>, <span>$resolver</span><span>); </span><span>2</span> <span>3</span> <span>$kernel</span> = <span>new</span> HttpCache(<span>$kernel</span>, <span>new</span> Store(__DIR__.'/cache'));
想对它做一下功能测试:
<span>1</span> <span>$client</span> = <span>new</span> Client(<span>$kernel</span><span>); </span><span>2</span> <span>$crawler</span> = <span>$client</span>->request('GET', '/hello/Fabien'<span>); </span><span>3</span> <span>4</span> <span>$this</span>->assertEquals('Fabien', <span>$crawler</span>->filter('p > span')->text());
想要一个好看的错误展示页面?
<span>1</span> <span>$dispatcher</span>->addSubscriber(<span>new</span> ExceptionListener(<span>function</span> (Request <span>$request</span><span>) { </span><span>2</span> <span>$msg</span> = 'Something went wrong! ('.<span>$request</span>->get('exception')->getMessage().')'<span>; </span><span>3</span> <span>4</span> <span>return</span> <span>new</span> Response(<span>$msg</span>, 500<span>); </span><span>5</span> }));
(1).转动一次;旋转一圈。 南朝 梁武帝 《白紵辞》:“短歌流目未肯前,含笑一转私自怜。” 唐 顾况 《悲歌》之二:“我心皎洁君不知,辘轳一转一惆怅。” 元 王实甫 《西厢记》第一本第一折:“怎当他临去秋波那一转!”《儿女英雄传》第四回:“且说那女子把那石头撂倒在平地上,用右手推着一转,找着那个关眼儿伸进两个指头去勾住了。”
(2).提炼一次。 晋 葛洪 《抱朴子·金丹》:“其一转至九转,迟速各有日数,多少以此知之耳。”
(3).计算一遍。 南朝 宋 刘义庆 《世说新语·文学》:“尝算浑天不合,诸弟子莫能解。或言 玄 ( 郑玄 )能者。 融 ( 马融 )令算,一转便决。”
(4).四周。《儒林外史》第十四回:“两边一望,一边是江,一边是湖,又有那山色一转围着。”《儒林外史》第三十回:“诸名士看这湖亭时,轩窗四起,一转都是湖水围绕。”
(1).转换勋阶一次。《新唐书·太宗纪》:“从伐 高丽 无功者,皆赐勋一转。”
(2).表数量。 清 翟灏 《通俗编·数目》引 李翊 《俗呼小录》:“ 杭州 以柴四圆箍为一转。”
ZDIC.NET 汉 典 网
【一转语】 禅宗机锋往来的关键处,称“玄关”。破“玄关”必须亲证实悟。以片言只语,拨转对方的心机,使之冲破“玄关”,“柳暗花明又一村”,谓之“转语”。《景德传灯录·百丈怀海禅师》指出:“古人只错对一转语,五百生堕野狐身。”可见“转语”的重要。举几个例子。问:“不起一念有过无过?”答:“须弥山。”又如问;“磨砖岂成镜耶?”答:“磨砖既不成镜,坐禅岂得成佛耶!”后亦用“一转语”指别出心裁。如宋·张元干《青玉案》词序:“贺方回所作,世间和韵者多矣。余经行松江,何啻百回,念欲下一转语。”也指用一二句话让人恍然大悟。如胡适《尝试篇》:“尝试成功自古无,放翁此语未必是;我今为下一转语,自古成功在尝试。”
This sentence should be considered a cliché, but the control of emotions and mood is not so good all the time. There will also be occasional anger, jealousy, and resentment. I have always said that I am a person who doesn't know how to hide my emotions, and all my happiness, anger, sorrow and joy are written on my face. At first glance, it sounds like it's a straightforward statement, but it's not. Until one day, when I was extremely sad and angry about something and tried to cover it up, a careful friend discovered me and said bluntly: You are really ugly when you have a straight face. It turns out that we don’t need to know how to hide bad emotions. If the bad emotions don’t go away, we can’t fundamentally change the surroundings; what we need to do is to know how to resolve the bad emotions. Nowadays, resources and information are developed, and there are many ways to read good texts and articles. I would like to share good articles with everyone. I hope we can all be selves who understand ourselves and know how to make ourselves happy and happy. -------------------------------------Shared dividing line-------- ---------------------------- [Reprinted] Article source: Tianji Documents In ancient times, physiognomy, a prediction technique, was formed, which was a specialized Physiognomy, which uses the information stored in a person's five senses to infer a person's misfortunes, blessings, good fortune, and misfortunes, is a household name among Chinese people. As the saying goes: People have one face. You can see a person's five senses and appearance at a glance, and it also gives people their first sense and impression. When you go to the street or go to a free market, take a walk and take a look to see who is a gentleman and who is a thief. You can tell them at a glance, because thieves have different eyesight from normal people. During the period of the National Revolution, China was in the midst of troubled times, with dragons and snakes mixed together, reckless heroes showing off, and social order in chaos. In the Shanghai Police Department, there was a master. A law-abiding policeman arrests all the thieves he sees. Every person he arrests after interrogation confesses that he has committed theft and bad deeds. He can catch ten and it is accurate to say ten. : The physiognomy he mastered is accurate and scientific. In fact, when a person is born, the good and bad fortunes in his life are all contained in the person's facial features. The person's facial features are an information map of a person's life, including the length of a person's lifespan, the early death of parents, the number of children, and the number of brothers. The blessings and misfortune of marriage are all reflected in people's five senses. Why is it that a kind-hearted person looks cunning in appearance, while a kind-hearted and vicious person looks cunning? This reflects an eternal philosophy. The heart is what people often say is the thinking activity deep inside, and it does not simply refer to the human heart. What you think in your heart can be reflected on your five senses. When there is something exciting or joyful in a person's heart, that person will smile a lot, letting others know that something joyful must have happened to him. On the contrary, when something sad happens to a person, the expression on his face is a look of mourning. In short, a person's happiness, anger, sadness, joy, sorrow, thought, fear, and surprise are all reflected in the five senses, and the five senses are a very accurate measuring instrument. There is a theory in the Huangdi Nei Jing that the external is derived from the inside, while the internal is expressed from the outside. When a person with stomach problems goes to see a doctor, the doctor diagnoses him by looking, smelling, asking questions, and incising. When the doctor sees that the patient's nose is red, he can tell that the person has stomach problems. , this is the expression of holographic theory. The same goes for people's thinking. When a person has a deep hatred for another person and wants to kill that person for revenge, his eyes are capable of spitting out fire, showing a fierce look, and showing murderous intent. When he When I wanted to find a fortune teller to tell me whether the operation would be successful, the fortune teller said: "You look murderous, please don't take risks." I know an old lady in her sixties who loves Zhou Yi. Everyone calls her Miao Po. The first time I met her was in the Triangle Flower Garden. She asked me to test her luck. I saw that she had three stripes under her left eye. The bottom stripe did not extend straight to the left, but went downward and to the left across her left cheekbone. I asked: Aunt Miao, is your little daughter at home? ? She replied: Oh, that’s why I predicted it. My youngest daughter ran away with a young man. Now I don’t know where she has gone? More than a month later, when I met Mrs. Miao again, she had already returned home from her little daughter's business. I saw that Mrs. Miao's silkworm stripes had straightened out. This shows that appearance changes with inner thoughts. After her little daughter left, she missed and worried about her all day long, and this thinking energy was reflected in her facial features. The sentence "Looks come from the heart, and the environment changes with the heart" comes from a Buddhist saying, and is often mentioned by many people... The rest of the full text >>