更好的编码方式?

时间:2010-11-10 12:15:38

标签: php

对此进行编码的最佳,最简单的方法是什么: 我有一个php文档,可以获取大部分页面请求(在路由配置中设置,使用代码点火器框架),并根据uri我想向用户显示不同的内容。例如:

http: // domain.tld/2010/  
Should show one type of content

http: // domain.tld/2010-nov/  
should show another type of content

http: // domain.tld/2010-nov-10/  
should show yet another type of content

http: // domain.tld/2010-nov-10-blog-post-title/  
should show once again another type of content

其他所有内容都应被视为产品,例如:
http:// domain.tld / light-bulb /
如果这样的产品不存在,则为404

以下是我目前获得的代码,但我觉得它太乱了。有任何建议如何使其更简单,更有效? (试图在这里正确地格式化它,但是让代码正确对齐似乎有点棘手,道歉)

此致 杰森
(必须在我的所有网址中添加空格,因为我是新的,不允许发布那么多网址)

$val is the uri (/2010-nov.......)

    function show_what($val){
 $arr=array("jan"=>01,"feb"=>02,"mar"=>03,"apr"=>04,"may"=>05,"jun"=>06,"jul"=>07,"aug"=>08,"sep"=>09,"oct"=>10,"nov"=>11,"dec"=>12);
 // first check to see if the uri starts with a year (4 digits)
 if(is_int((int)substr($val,0,4)) && (int)substr($val,0,4)!=0){
  // Get all posts for specified YEAR
  if(strlen($val)==4){
   // Show all blog posts for specified year
   // example: http: // domain.tld/2010/

  // Get all posts for specified YEAR and MONTH
  }elseif(strlen($val)==8 && substr($val,4,1)=="-" && array_key_exists(substr($val,5,3),$arr)){
   // show all blog posts for specified year and month
   // example: http: // domain.tld/2010-nov/

  // Get all posts for specified YEAR, MONTH and DAY OR! get specified post
  }elseif(strlen($val)>=11 && substr($val,4,1)=="-" && array_key_exists(substr($val,5,3),$arr) && substr($val,8,1)=="-" && is_int((int)substr($val,9,2)) && (int)substr($val,9,2)!=0){

   // Get all posts for specified YEAR, MONTH and DAY
   if(strlen($val)==11){
    // show all blog posts for specified year, month and day
    // example: http: // domain.tld/2010-nov-10/

   // Get specified post
   }elseif(substr($val,11,1)=="-"){
    // show specified post or 404
    // example: http: // domain.tld/2010-nov-10-blog-post-title/
   }else{
    // "Not a valid article url<Br/>";
    // example: http: // domain.tld/2010-nov-10there-is-a-dash-missing-after-day/
   }
  }else{
   // 404, not a real date
  }
 }else{
  // show product with current uri or if it doesnt exist, 404.
 }
}

5 个答案:

答案 0 :(得分:4)

我不是一个PHP人,实际上不知道如何在PHP上实现它,但你绝对应该在Apache中使用mod_rewrite或IIS 7中的URL Rewrite寻找URL Rewrite,并利用正则表达式,这样你就不会需要解析字符串。

答案 1 :(得分:2)

您可以使用正则表达式来解析URL部分。例如:

(?<Year>[0-9]{4})
(-
  (?<Month>[a-zA-Z]+)
  (-
    (?<Day>[0-9]{1,2})
    (-
      (?<Slugg>.*)
    )?
  )?
)?

(几乎让你想起Lisp,不是吗?)

根据存在和有效的部分,执行适当的逻辑。

这是一个让您入门的测试示例。它包括我的正则表达式解决方案和使用其他人建议的字符串拆分的解决方案。

<?php

function getParts($source) {
    $re = '/^
    (?<Year>[0-9]{4})
    (-
      (?<Month>[a-zA-Z]+)
      (-
        (?<Day>[0-9]{1,2})
        (-
          (?<Slugg>.*)
        )?
      )?
    )?
    $/';

    $re = str_replace(array(' ', "\n", "\r", "\t"), '', $re);   // Strip whitespace that made the RE readable

    $matches = null;

    if (!preg_match($re, $source, $matches)) {
        return array('title' => $source);
    }

    $ret = array();

    if (!$matches['Year']) {
        return $ret;
    }

    $ret['year'] = (int) $matches['Year'];

    if (!$matches['Month']) {
        return $ret;
    }

    $monthToNumber = array('jan' => 1, 'feb' => 2, 'mar' => 3, 'apr' => 4, 'may' => 5, 'jun' => 6, 'jul' => 7, 'aug' => 8, 'sep' => 9, 'oct' => 10, 'nov' => 11, 'dec' =>>
    $monthName = strtolower($matches['Month']);

    if (!array_key_exists($monthName, $monthToNumber)) {
        return $ret;
    }

    $ret['month'] = $monthToNumber[$monthName];

    if (!$matches['Day']) {
        return $ret;
    }

    $ret['day'] = (int) $matches['Day'];

    if (!$matches['Slugg']) {
        return $ret;
    }

    $ret['title'] = $matches['Slugg'];

    return $ret;
}

function getParts2($source) {
    $ret = array();
    $errorRet = array('title' => $source);

    $rawParts = explode('-', $source, 4);

    if (count($rawParts) < 1 || !is_numeric($rawParts[0])) {
        return $errorRet;
    }

    $ret['year'] = (int) $rawParts[0];

    if (count($rawParts) < 2) {
        return $ret;
    }

    $monthToNumber = array('jan' => 1, 'feb' => 2, 'mar' => 3, 'apr' => 4, 'may' => 5, 'jun' => 6, 'jul' => 7, 'aug' => 8, 'sep' => 9, 'oct' => 10, 'nov' => 11, 'dec' =>>
    $monthName = strtolower($rawParts[1]);

    if (!array_key_exists($monthName, $monthToNumber)) {
        return $errorRet;
    }

    $ret['month'] = $monthToNumber[$monthName];

    if (count($rawParts) < 3) {
        return $ret;
    }

    $ret['day'] = (int) $rawParts[2];

    if (count($rawParts) < 4) {
        return $ret;
    }

    $ret['title'] = $rawParts[3];

    return $ret;
}

function test($testFunc, $source, $expected) {
    $actual = call_user_func($testFunc, $source);

    if ($actual !== $expected) {
        echo "Test failed;\n";
        echo "Input: ";
        var_dump($source);
        echo "Actual: ";
        var_dump($actual);
        echo "Expected: ";
        var_dump($expected);
    }
}

foreach (array('getParts', 'getParts2') as $testFunc) {
    test($testFunc, '2010', array('year' => 2010));
    test($testFunc, '2010-nov', array('year' => 2010, 'month' => 11));
    test($testFunc, '2010-nov-10', array('year' => 2010, 'month' => 11, 'day' => 10));
    test($testFunc, '2010-nov-10-blog-post-title', array('year' => 2010, 'month' => 11, 'day' => 10, 'title' => 'blog-post-title'));
    test($testFunc, 'light-bulb', array('title' => 'light-bulb'));
}

答案 2 :(得分:1)

你可以简单地将它分解为数组

$array = explode('-',$val);

并创建一个类似

的数组大小的switch case
   switch(count($array){
    # is like 2010
    case 1:
       // Show all blog posts for specified year
       // example: http: // domain.tld/2010/
       $year = $array[0];
    break;
    .....
    }

答案 3 :(得分:0)

将部分拆分为连字符,如下所示:

$parts = explode('-', $url)
if (count($parts) == 2) {
    $year = $parts[0];
    $month = $parts[1];
} else if (count($parts) == 3) {

答案 4 :(得分:0)

你应该看看CodeIgniter Framework。像URL ReWrite这样的东西都构建在框架中,它很容易使用+闪电般快速。我从2008年开始使用它。