开屏广告-php 服务端部分

其实服务端没什么好说,就是那几个字段,那就几个逻辑。后面我会贴出来,关键是要理解服务端开发整体的结构框架,其实对我所在公司这样的中小企业来说,最最核心部分还是服务端,其实对大公司也一样,但是大公司的 APP 动辄上百万甚至更多,对用户体验,客户端架构设计有着更高的要求。如果想做服务端,关键是 php 环境搭建。这里给大家介绍下我自己学习过程中的材料,不过多讲解,毕竟服务端我也半吊子,『师傅领进门,修行靠个人』。

我负责的项目服务端目前是基于Symfony2框架做的。
Symfony2官方文档:http://www.symfonychina.com/doc/current/setup.html
其实对一些刚入门服务端的朋友,看Symfony2官方文档还是有一些吃力的,这里介绍一个非常基础Symfony2框架视频教程:http://www.imooc.com/learn/244
这个教程也是刚踏坑时候看的,虽然不长,非常夯实基础,对Symfony2环境搭建,目录结构,路由,表单,模板引擎,数据库基础知识等等都有非常详细的解释。

另外我们在用的第三方管理后台sonata admin :http://www.newlifeclan.com/symfony/archives/520
bundle的github地址:https://github.com/sonata-project/SonataAdminBundle

理解了Symfony2框架,我们在看下我们开屏广告的服务端代码部分:
数据库表字段:


image.png

熟悉 Symfony2 都知道,Symfony2其实弱化了数据库操作的,数据表的创建不需要自己手动去添加。只要 php 生成好对象属性,数据表的构建,查询等等都是Symfony2去帮助我们完成的,我们只要以面向对象的方式去读写就 ok 了,这很牛逼。

下面我代码发一下吧 entity部分其实只有字段定义需要手动写,get set方法和Repository类调用app/console generate:doctrine:entities+entity 名称即可生成。
当然Repository里的业务逻辑需要自己添加。
之后调用:app/console doctrine:schema:update --dump-sql --force -C 会生成数据库表。(这也就Symfony2厉害的地方,开发者只用关心自己业务逻辑即可。)
MainAdver.php

<?php
/**
 * Created by PhpStorm.
 * User: apple
 * Date: 16/1/25
 * Time: 下午2:03
 */

namespace Wan\MainBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\HttpFoundation\File\UploadedFile;

/**
 * MainAdver
 *
 * @ORM\Table(name="w_main_adver")
 * @ORM\Entity(repositoryClass="Wan\MainBundle\Entity\MainAdverRepository")
 */
class MainAdver
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * Title
     * @var string
     * @ORM\Column(name="title", type="string", length=150, nullable=false)
     */
    private $title;


    /**
     * 活动状态
     * @var integer
     *
     * @ORM\Column(name="type", type="integer")
     * 0:已结束,1:安卓,2:IOS 3:全部
     */
    protected $type = 1;


    /**
     *
     * @var string
     * @ORM\Column(name="pic", type="string", length=500, nullable=false)
     */
    private $pic;

    /**
     *
     * @var string
     * @ORM\Column(name="link", type="string", length=1000, nullable=false)
     */
    private $link;


    private $file;

    /**
     *
     * @var User
     * @ORM\ManyToOne(targetEntity="Wan\UserBundle\Entity\User")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     */
    protected $user;


    /**
     * 创建时间
     * @Gedmo\Timestampable(on="create")
     * @ORM\Column(name="created_at", type="datetime", nullable=false)
     */
    private $createdAt;

    /**
     * @var \DateTime $updated
     *
     * @Gedmo\Timestampable(on="update")
     * @ORM\Column(name="updated", type="datetime")
     */
    private $updated;

    /**
     * 活动-开始
     * @ORM\Column(name="start_at", type="datetime", nullable=true)
     */
    private $startAt;

    /**
     * 活动-结束
     * @ORM\Column(name="end_at", type="datetime", nullable=true)
     */
    private $endAt;

    /**
     * 是否显示
     * @var bool
     *
     * @ORM\Column(name="is_show", type="boolean",nullable=false, options={"default" = true})
     */
    protected $isShow = true;

    public function setFile(UploadedFile $file)
    {
        $this->file = $file;
        return $this;
    }

    public function getFile()
    {
        return $this->file;
    }


    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set title
     *
     * @param string $title
     * @return MainAdver
     */
    public function setTitle($title)
    {
        $this->title = $title;

        return $this;
    }

    /**
     * Get title
     *
     * @return string
     */
    public function getTitle()
    {
        return $this->title;
    }

    /**
     * Set pic
     *
     * @param string $pic
     * @return MainAdver
     */
    public function setPic($pic)
    {
        $this->pic = $pic;

        return $this;
    }

    /**
     * Get pic
     *
     * @return string
     */
    public function getPic()
    {
        return $this->pic;
    }

    /**
     * Set createdAt
     *
     * @param \DateTime $createdAt
     * @return MainAdver
     */
    public function setCreatedAt($createdAt)
    {
        $this->createdAt = $createdAt;

        return $this;
    }

    /**
     * Get createdAt
     *
     * @return \DateTime
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }

    /**
     * Set updated
     *
     * @param \DateTime $updated
     * @return MainAdver
     */
    public function setUpdated($updated)
    {
        $this->updated = $updated;

        return $this;
    }

    /**
     * Get updated
     *
     * @return \DateTime
     */
    public function getUpdated()
    {
        return $this->updated;
    }

    /**
     * Set startAt
     *
     * @param \DateTime $startAt
     * @return MainAdver
     */
    public function setStartAt($startAt)
    {
        $this->startAt = $startAt;

        return $this;
    }

    /**
     * Get startAt
     *
     * @return \DateTime
     */
    public function getStartAt()
    {
        return $this->startAt;
    }

    /**
     * Set endAt
     *
     * @param \DateTime $endAt
     * @return MainAdver
     */
    public function setEndAt($endAt)
    {
        $this->endAt = $endAt;

        return $this;
    }

    /**
     * Get endAt
     *
     * @return \DateTime
     */
    public function getEndAt()
    {
        return $this->endAt;
    }

    /**
     * Set isShow
     *
     * @param boolean $isShow
     * @return MainAdver
     */
    public function setIsShow($isShow)
    {
        $this->isShow = $isShow;

        return $this;
    }

    /**
     * Get isShow
     *
     * @return boolean
     */
    public function getIsShow()
    {
        return $this->isShow;
    }

    /**
     * Set user
     *
     * @param \Wan\UserBundle\Entity\User $user
     * @return MainAdver
     */
    public function setUser(\Wan\UserBundle\Entity\User $user = null)
    {
        $this->user = $user;

        return $this;
    }

    /**
     * Get user
     *
     * @return \Wan\UserBundle\Entity\User
     */
    public function getUser()
    {
        return $this->user;
    }


    /**
     * 1 未开始 2 已开始 3已结束
     * @return int
     */
    public function getState()
    {

        $now = new \DateTime();
        if ($now->getTimestamp() < $this->getStartAt()->getTimestamp()) {
            return MainAdverRepository::STATUS_NO;
        }

        if ($now->getTimestamp() < $this->getEndAt()->getTimestamp()) {
            return MainAdverRepository::STATUS_ING;
        }
        return MainAdverRepository::STATUS_ED;
    }

    /**
     * @return int
     */
    public function getType()
    {
        return $this->type;
    }

    /**
     * @param int $type
     */
    public function setType($type)
    {
        $this->type = $type;
        return $this;
    }

    /**
     * @return string
     */
    public function getLink()
    {
        return $this->link;
    }

    /**
     * @param string $link
     */
    public function setLink($link)
    {
        $this->link = $link;
        return $this;
    }


    /**
     * 状态描述
     * @return mixed
     */
    public function getStateDescribe()
    {
        return MainAdverRepository::$STATUS[$this->getState()];
    }

    public function getTypeDecribe()
    {
        return MainAdverRepository::$TYPE[$this->getType()];
    }
}

Repository:

<?php

namespace Wan\MainBundle\Entity;

use Doctrine\ORM\Query;
use Doctrine\ORM\QueryBuilder;
use Wan\CommonBundle\Classes\MainClass;
use Wan\CommonBundle\Core\WanEntityRepository;
use Wan\CommonBundle\Utils\QArray2;
use Wan\Lib\SiteUtils;

/**
 * MainAdverRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class MainAdverRepository extends WanEntityRepository
{
    const STATUS_ALL = 1;
    const STATUS_NO = 2;
    const STATUS_ING = 3;
    const STATUS_ED = 4;


    public static $STATUS = array(
        self::STATUS_ALL => '全部',
        self::STATUS_NO => '未开始',
        self::STATUS_ING => '进行中',
        self::STATUS_ED => '已结束'
    );


    const TYPE_ANDROID = 1;
    const TYPE_IOS = 2;
    const TYPE_ALL = 3;


    public static $TYPE = array(
        self::TYPE_ANDROID => '安卓',
        self::TYPE_IOS => 'IOS',
        self::TYPE_ALL => '全部',

    );

    protected function queryByType($type, array $critical = array(), array $options = array())
    {
        $qb = $this->createQueryBuilder('E');

        if (!isset($options['orderby'])) {
            $options['orderby'] = array('updated DESC');
        }
        $typeArray = array();
        $typeArray[] = self::TYPE_ALL;
        $typeArray[] = $type;

        $strSubs = implode(",", $typeArray);
        $qb->andWhere("E.type in ({$strSubs})");
        $this->applyOptions($qb, 'E', $options);
        $this->appendSimpleCritical($qb, 'E', $critical);
        $this->appendSimpleOrder($qb, 'E', $options['orderby']);

        return $qb;
    }

    private function applyOptions(QueryBuilder $builder, $alias, array $options)
    {
        $now = new \DateTime();
        $nowFormat = $now->format("Y-m-d H:i:s");
        $builder->andWhere("E.startAt < '{$nowFormat}' and E.endAt > '{$nowFormat}'");
        $builder->andWhere("E.isShow = 1");


    }

    public function toApiValue($doc)
    {
        if (!$doc || !$doc instanceof MainAdver) {
            return array();
        }

        $ret = array(
            "id" => $doc->getId(),
            'pic' => $doc->getPic() ?: '',
            'link' => (string)$doc->getLink(),
            "endtime" => $doc->getEndAt()->getTimestamp(),
        );
        return $ret;
    }
}

这里我们的Repository 是继承 WanEntityRepository WanEntityRepository又继承EntityRepository,我们在WanEntityRepository做了一些自己的结构封装。

Ctroller 里的查询方法:

$repAdver = $em->getRepository("WanMainBundle:MainAdver");
        $adverDate = array();
        $advers = $repAdver->findByType($type, array(), ["limit" => 1]);
        foreach ($advers as $val) {
            $adverDate[] = $repAdver->toApiValue($val);
        }

接口返回给$adverDate给客户端即可,这里我就不放出 sonata admin 里的部分代码,想了解朋友去看下sonata admin 管理后台如何配置和创建。

其实,php 服务端的部分业务和功能都没什么好说,根本还是要对Symfony2有升入了解。

另外介绍另外一个 PHP 框架:laravel :http://www.golaravel.com
这个我也没看过,等我看了可以再来介绍下。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • Awesome PHP 一个PHP资源列表,内容包括:库、框架、模板、安全、代码分析、日志、第三方库、配置工具、W...
    guanguans阅读 5,753评论 0 47
  • 3月26日傍晚的铁仔山,有点《头文字D》中秋明山的感觉,不蹬腿只抬腿,跟随RAP的音乐,很轻松地跑着,跑完发现这是...
    周一城阅读 447评论 1 1
  • 周一啦周一啦,今天六点半闹钟响起来了,但我起不来,躺在床上听了一个小时的书才不得不起来,身体的疲惫让我不得不正视自...
    小木头君阅读 140评论 0 0
  • 人之一生,可能会爱许多,也会被许多所爱.(别问我许多是谁) 他可以是爱好,可以是习惯.或者是生命体, 甚至于概念....
    菲妮阅读 657评论 11 15