获取YII中的所有“页面”?

时间:2013-01-14 09:37:49

标签: php yii sitemap

我正在尝试创建自己的xml站点地图。一切都已完成,除了我认为最容易的部分。如何获得网站上所有页面的列表?我在/ site文件夹和其他一些文件夹中有很多视图。有没有办法明确请求他们的URL或可能通过控制器?

我不想使用扩展程序

5 个答案:

答案 0 :(得分:9)

您可以使用反射来遍历所有控制器的所有方法:

Yii::import('application.controllers.*');
$urls = array();

$directory = Yii::getPathOfAlias('application.controllers');
$iterator = new DirectoryIterator($directory);
foreach ($iterator as $fileinfo)
{
    if ($fileinfo->isFile() and $fileinfo->getExtension() == 'php')
    {
        $className = substr($fileinfo->getFilename(), 0, -4); //strip extension
        $class = new ReflectionClass($className);

        foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method)
        {
            $methodName = $method->getName();
            //only take methods that begin with 'action', but skip actions() method
            if (strpos($methodName, 'action') === 0 and $methodName != 'actions')
            {   
                $controller = lcfirst(substr($className, 0, strrpos($className, 'Controller')));
                $action = lcfirst(substr($methodName, 6));
                $urls[] = Yii::app()->createAbsoluteUrl("$controller/$action");
            }
        }
    }
}

答案 1 :(得分:1)

您需要知道要在sitemap.xml中包含哪些内容,我真的不认为您希望在sitemap.xml中包含所有页面,或者您是否真的想要包含诸如site.com/之类的内容article / edit / 1?

也就是说,您可能只想要控制器中view操作的结果。事实是,你需要知道你想要索引什么。

不要考虑控制器/操作/视图,而是考虑系统中要索引的资源,无论是文章还是页面,它们都在您的数据库中或以某种方式存储,因此您可以列出它们,并且它们有一个标识它们的URI,获取URI是一个调用几个函数的问题。

答案 2 :(得分:1)

有两种可能性 -

案例1:

您正在运行静态网站,然后您可以在1个文件夹中找到所有HTML - protected / views / site / pages http://www.yiiframework.com/wiki/22/how-to-display-static-pages-in-yii/

案例2:

网站是动态的。生成和重新生成站点地图等任务可以归类为后台任务。

可以通过使用 - WGET GET lynx 命令

或者,您可以将CronController创建为 CConsoleCommand 。如何使用YII中的命令显示在下面的链接中 - http://tariffstreet.com/yii/2012/04/implementing-cron-jobs-with-yii-and-cconsolecommand/

Sitemap是一个列出您网站网址的XML。但它不止于此。 它可以帮助您可视化网站的结构,您可能有

  • 类别
  • 子类。

在制作有用的 扩展程序 时,可以在设计之前考虑以上几点。

Wordpress 这样的框架提供了生成分类站点地图的方法。 因此,每个页面的元数据都是从之前存储并使用它发现的元数据和组页面。

@Pavle 建议的反思解决方案很好,应该是可行的方法。 考虑可能有部分视图,您可能希望也可能不希望将它们列为单独的链接。

因此,您希望为创建扩展所付出的努力也取决于其中一些。

您可以要求用户列出配置文件中的所有变量,然后从那里开始,您必须使用 reflection 和解析页面并寻找正则表达式

对于ex - 基于模块名称,您可以先将它们分组,模块内的控制器可以形成子组。

答案 3 :(得分:1)

第一种方法可能是迭代视图文件,但是您必须考虑到在某些情况下,视图不是页面目标,而是使用CController::renderPartial()方法包含在其他页面中的页面部分。通过探索CController的类引用,我发现了CController::actions()方法。

所以,我没有找到任何 Yii方式来迭代CController的所有动作,但我使用php在我的一个项目中迭代SiteController的所有方法并过滤它们这些是前缀'action',这是我的动作前缀,这是示例

class SiteController extends Controller{
    public function actionTest(){
        echo '<h1>Test Page!</h1></p>';
        $methods = get_class_methods(get_class($this));
        // The action prefix is strlen('action') = 6
        $actionPrefix = 'action';
        $reversedActionPrefix = strrev($actionPrefix);
        $actionPrefixLength = strlen($actionPrefix);
        foreach ($methods as $index=>$methodName){
            //Always unset actions(), since it is not a controller action itself and it has the prefix 'action'
            if ($methodName==='actions') {
                unset($methods[$index]);
                continue;
            }
            $reversedMethod = strrev($methodName);
            /* if the last 6 characters of the reversed substring === 'noitca', 
             * it means that $method Name corresponds to a Controller Action,
             * otherwise it is an inherited method and must be unset.
             */
            if (substr($reversedMethod, -$actionPrefixLength)!==$reversedActionPrefix){
                unset($methods[$index]);
            } else $methods[$index] = strrev(str_replace($reversedActionPrefix, '', $reversedMethod,$replace=1));
        }
        echo 'Actions '.CHtml::listBox('methods', NULL, $methods);
    }
    ...
}

我得到的输出是......

All the actions in a ListBox!

我确信它可以进一步完善,但这种方法适用于你拥有的任何控制器......

所以你需要做的是:

对于每个Controller:使用上述方法过滤掉类的所有非动作方法。您可以构建一个像

这样的关联数组
array(
    'controllerName1'=>array(
        'action1_1',
        'action1_2'),
    'controllerName2'=>array(
        'action2_1',
        'action2_2'),
);

我会在我的SiteController中为此添加一个静态方法getAllActions()。

get_class_methodsget_classstrrevstrlen都是PHP函数。

答案 4 :(得分:1)

根据您的问题: 1.如何获得网站上所有页面的列表?

基于Yii的模块/控制器/动作/ action_params方式以及构建SEO站点地图的需要。

  1. 由于您的动作参数无限期地变化,因此很难自动解析以获取所有网址。虽然你可以简单地通过构造得到控制器/动作 Pavle Predic。当您有针对SEO的自定义(SERF)URL规则时,就会出现复杂性。
  2. 下一个最佳解决方案是拥有一个内容数据库,您知道如何通过url规则获取每个内容,然后通过cron控制台作业创建所有要保存为sitemap.xml的URL。

    希望这有帮助!