控制反转(IOC)和依赖注入(DI)

概念

IOC(inversion of control)控制反转模式;控制反转是将组件间的依赖关系从程序内部提到外部来管理;
DI(dependency injection)依赖注入模式;依赖注入是指将组件的依赖通过外部以参数或其他形式注入;
两个说法本质上是一个意思。
例如:

class DbMysql
{
    public function query(){}
}
class Controller
{
    public $db;
    public function __construct()
    {
        $this->db = new DbMysql();
    }
    public function action()
    {
        $this->db->query();
    }
}
$c = new Controller();
$c->action();

Controller类中的action方法需要用到DbMysql类中的query方法,所以Controller类就对DbMysql类产生了依赖,Controller类和DbMysql类之间的耦合度就比较高,因为当DbMysql类的构造函数发生改变的时候,比如由现在的没有参数变成有参数了,参数数量改变了,那么Controller类中的代码都要做出相应改变。或者说我们现在需要将DbMysql类换成另一个DbOracle类,Controller类中要做出的改变甚至更大。
看下面的另一种写法:

class DbMysql
{
    public function query(){}
}
class Controller
{
    public $db;
    public function __construct($dbMysql)
    {
        $this->db = $dbMysql;
    }
    public function action()
    {
        $this->db->query();
    }
}
$db = new DbMysql();
$c = new Controller($db);
$c->action();

Controller类中不需要实例化DbMysql,而是将DbMysql类的实例作为参数传递(或者单独写一个接收实例的方法处理),这样Controller类就完全不用管DbMysql是怎么样实例的,而是仅仅调用DbMysql中的query方法就行了。这种模式就是依赖注入。第一个例子中Controller类负责实例DbMysql,也就是说Controller类控制着实例DbMysql类的主动权,而第二个例子中将这个主动权提出到Controller类的外面,所以也叫做控制反转。
这样看起来还不错,但是如果我们需要很多类,而且需要自己写的时候弄清楚,每一个类依赖什么类,这样太烦,如果有一个类能够帮我们搞定这个动作那就太爽了。而事实上有这个类,这个类就叫做IOC容器。

示例分析

下面我们通过示例的方式一步一步的来分析。

示例一

class DbMysql
{
    public function __construct($host, $name, $pwd)
    {
        // do something
    }

    public function query()
    {
        echo __METHOD__ . PHP_EOL;
    }
}

class DbRedis
{
    public function __construct($host, $name, $pwd)
    {
        // do something
    }

    public function set()
    {
        echo __METHOD__ . PHP_EOL;
    }
}

class controller
{
    public $mysql;
    public $redis;

    public function __construct()
    {
        $this->mysql = new DbMysql('host', 'name', 'pwd');
        $this->redis = new DbRedis('host', 'name', 'pwd');
    }

    public function action()
    {
        $this->mysql->query();
        $this->redis->set();
    }
}

$c = new Controller();
$c->action();
/**
 * 输出:
 * DbMysql::query
 * DbRedis::set
 */

普通的实现方式,耦合度高。

示例二

class DbMysql
{
    public function __construct($host, $name, $pwd)
    {
        // do something
    }

    public function query()
    {
        echo __METHOD__ . PHP_EOL;
    }
}

class DbRedis
{
    public function __construct($host, $name, $pwd)
    {
        // do something
    }

    public function set()
    {
        echo __METHOD__ . PHP_EOL;
    }
}

class controller
{
    public $mysql;
    public $redis;

    public function __construct($mysql, $redis)
    {
        $this->mysql = $mysql;
        $this->redis = $redis;
    }

    public function action()
    {
        $this->mysql->query();
        $this->redis->set();
    }
}

$mysql = new DbMysql('host', 'name', 'pwd');
$redis = new DbRedis('host', 'name', 'pwd');
$c = new Controller($mysql, $redis);
$c->action();
/**
 * 输出:
 * DbMysql::query
 * DbRedis::set
 */

实现了依赖注入和控制反转,但是没有使用容器类。

示例三

class DbMysql
{
    public function __construct($host, $name, $pwd)
    {
        // do something
    }

    public function query()
    {
        echo __METHOD__ . PHP_EOL;
    }
}

class DbRedis
{
    public function __construct($host, $name, $pwd)
    {
        // do something
    }

    public function set()
    {
        echo __METHOD__ . PHP_EOL;
    }
}

class controller
{
    public $mysql;
    public $redis;

    public function __construct($mysql, $redis)
    {
        $this->mysql = $mysql;
        $this->redis = $redis;
    }

    public function action()
    {
        $this->mysql->query();
        $this->redis->set();
    }
}

class Container
{

    public $bindings = [];

    public function bind($key, Closure $value)
    {
        $this->bindings[$key] = $value;
    }

    public function make($key)
    {
        $new = $this->bindings[$key];
        return $new();
    }

}

$app = new Container();
$app->bind('mysql', function () {
    return new DbMysql('host', 'name', 'pwd');
});
$app->bind('redis', function () {
    return new DbRedis('host', 'name', 'pwd');
});
$app->bind('controller', function () use ($app) {
    return new Controller($app->make('mysql'), $app->make('redis'));
});
$controller = $app->make('controller');
$controller->action();
/**
 * 输出:
 * DbMysql::query
 * DbRedis::set
 */

实现了基本的容器类,容器类中有两个方法,bind和make,一个是绑定操作,一个是实例化操作。将每一个需要使用到的类使用关键字绑定到容器类中去,但是每一个类仍然需要手动去实例化,这里引入了闭包函数,主要作用是在调用的时候才真正去实例化,而如果仅仅是绑定了一个类,是不会实例化这个类的。

示例四

class T
{
    public $t;
}

class X
{
    public $x;

    private function __construct()
    {
    }
}

class Y
{
    public $x;

    public function __construct()
    {
    }
}

interface Is
{
}

class Sis implements Is
{

}

class S
{
    public $s;

    public function __construct(string $s, int $i, array $a, Is $object)
    {
        $this->s = $s;
    }
}

function reflectionClass($className, array $inParams = [])
{
    $reflection = new ReflectionClass($className);
    // isInstantiable() 方法判断类是否可以实例化
    $isInstantiable = $reflection->isInstantiable();
    if ($isInstantiable) {
        // getConstructor() 方法获取类的构造函数,为NULL没有构造函数
        $constructor = $reflection->getConstructor();
        if (is_null($constructor)) {
            // 没有构造函数直接实例化对象返回
            return new $className;
        } else {
            // 有构造函数
            $params = $constructor->getParameters();
            if (empty($params)) {
                // 构造函数没有参数,直接实例化对象返回
                return new $className;
            } else {
                // 构造函数有参数,将$inParams传入实例化对象返回
                return $reflection->newInstanceArgs($inParams);
            }
        }
    }
    return null;
}

$t = reflectionClass('T');
var_dump($t instanceof T);
$x = reflectionClass('X');
var_dump($x instanceof X);
$x = reflectionClass('Y');
var_dump($x instanceof Y);
$s = reflectionClass('S', ['asdf', 123, [1, 2], (new Sis)]);
var_dump($s instanceof S);
/**
 * 输出:
 * bool(true)
 * bool(false)
 * bool(true)
 * bool(true)
 */

引入反射类,他的作用是可以实例化一个类,和new操作一样。但是实例化一个类所需要的参数,他都能自动检测出来。并且能够检测出来这个参数是不是一个继承了接口的类。上面说一个类依赖另一个类,然后将另一个类作为参数注入,这个反射能够检测出一个类实例化的时候需要什么样的类,好像有点眉目了是吧。

示例五

class DbMysql
{
    public function __construct($host, $name, $pwd)
    {
        // do something
    }

    public function query()
    {
        echo __METHOD__ . PHP_EOL;
    }
}

class DbRedis
{
    public function __construct($host, $name, $pwd)
    {
        // do something
    }

    public function set()
    {
        echo __METHOD__ . PHP_EOL;
    }
}

class controller
{
    public $mysql;
    public $redis;

    public function __construct($mysql, $redis)
    {
        var_dump($mysql);var_dump($redis);
        $this->mysql = $mysql;
        $this->redis = $redis;
    }

    public function action()
    {
        is_object($this->mysql) && $this->mysql->query();
        is_object($this->redis) && $this->redis->set();
    }
}

class Container
{

    public $bindings = [];

    public function bind($key, $value)
    {
        if (!$value instanceof Closure) {
            $this->bindings[$key] = $this->getClosure($value);
        }
        else{
            $this->bindings[$key] = $value;
        }
    }

    public function getClosure($value)
    {
        return function () use ($value) {
            return $this->build($value);
        };
    }

    public function make($key)
    {
        if (isset($this->bindings[$key])) {
            return $this->build($this->bindings[$key]);
        }
        return $this->build($key);
    }

    public function build($value)
    {
        if ($value instanceof Closure) {
            return $value();
        }
        // 实例化反射类
        $reflection = new ReflectionClass($value);
        // isInstantiable() 方法判断类是否可以实例化
        $isInstantiable = $reflection->isInstantiable();
        if ($isInstantiable) {
            // getConstructor() 方法获取类的构造函数,为NULL没有构造函数
            $constructor = $reflection->getConstructor();
            if (is_null($constructor)) {
                // 没有构造函数直接实例化对象返回
                return new $value;
            } else {
                // 有构造函数
                $params = $constructor->getParameters();
                if (empty($params)) {
                    // 构造函数没有参数,直接实例化对象返回
                    return new $value;
                } else {
                    $dependencies = [];
                    // 构造函数有参数
                    foreach ($params as $param) {
                        $dependency = $param->getClass();
                        if (is_null($dependency)) {
                            // 构造函数参数不为class,返回NULL
                            $dependencies[] = NULL;
                        } else {
                            // 类存在创建类实例
                            $dependencies[] = $this->make($param->getClass()->name);
                        }
                    }
                    return $reflection->newInstanceArgs($dependencies);
                }
            }
        }
        return null;
    }

}

$app = new Container();
$app->bind('mysql', function () {
    return new DbMysql('host', 'name', 'pwd');
});
$app->bind('redis', function () {
    return new DbRedis('host', 'name', 'pwd');
});
$app->bind('controller', 'controller');
$controller = $app->make('controller');
$controller->action();
/**
 * 输出:
 * NULL
 * NULL
 */

容器类中引入反射,容器类bind方法升级,不仅仅支持闭包绑定,而且支持类名绑定。示例三中的bind方法仅仅支持绑定一个关键字为闭包,而类的实例操作,需要写到闭包函数中去。现在有了反射,可以直接使用类名,反射会根据类名自动去实例化这个类。
但是这个例子中输出两个NULL,Controller类的两个参数均为NULL,反射类并没有自动去找到Controller依赖的DbMysql和DbRedis去实例化。这是为什么呢?现在就需要引入另一个东西,针对接口编程。
这个例子中我们知道Controller类的两个参数是类,但是我们定义的构造函数中并没有声明,现在这种定义方式的两个参数,是类,是字符串,是整型,完全没区别的,反射类无法检测出这两个参数是类,我们的反射方法里面如果检测到构造函数的参数不是类直接返回NULL,所以这里输出了两个NULL。

实例六

interface SMysql
{
    public function query();
}

class DbMysql implements SMysql
{
    public function __construct($host, $name, $pwd)
    {
        // do something
    }

    public function query()
    {
        echo __METHOD__ . PHP_EOL;
    }
}

interface SRedis
{
    public function set();
}

class DbRedis implements SRedis
{
    public function __construct($host, $name, $pwd)
    {
        // do something
    }

    public function set()
    {
        echo __METHOD__ . PHP_EOL;
    }
}

class controller
{
    public $mysql;
    public $redis;

    public function __construct(SMysql $mysql, SRedis $redis)
    {
        $this->mysql = $mysql;
        $this->redis = $redis;
    }

    public function action()
    {
        is_object($this->mysql) && $this->mysql->query();
        is_object($this->redis) && $this->redis->set();
    }
}

class Container
{

    public $bindings = [];

    public function bind($key, $value)
    {
        if (!$value instanceof Closure) {
            $this->bindings[$key] = $this->getClosure($value);
        } else {
            $this->bindings[$key] = $value;
        }
    }

    public function getClosure($value)
    {
        return function () use ($value) {
            return $this->build($value);
        };
    }

    public function make($key)
    {
        if (isset($this->bindings[$key])) {
            return $this->build($this->bindings[$key]);
        }
        return $this->build($key);
    }

    public function build($value)
    {
        if ($value instanceof Closure) {
            return $value();
        }
        // 实例化反射类
        $reflection = new ReflectionClass($value);
        // isInstantiable() 方法判断类是否可以实例化
        $isInstantiable = $reflection->isInstantiable();
        if ($isInstantiable) {
            // getConstructor() 方法获取类的构造函数,为NULL没有构造函数
            $constructor = $reflection->getConstructor();
            if (is_null($constructor)) {
                // 没有构造函数直接实例化对象返回
                return new $value;
            } else {
                // 有构造函数
                $params = $constructor->getParameters();
                if (empty($params)) {
                    // 构造函数没有参数,直接实例化对象返回
                    return new $value;
                } else {
                    $dependencies = [];
                    // 构造函数有参数
                    foreach ($params as $param) {
                        $dependency = $param->getClass();
                        if (is_null($dependency)) {
                            // 构造函数参数不为class,返回NULL
                            $dependencies[] = NULL;
                        } else {
                            // 类存在创建类实例
                            $dependencies[] = $this->make($param->getClass()->name);
                        }
                    }
                    return $reflection->newInstanceArgs($dependencies);
                }
            }
        }
        return null;
    }

}

$app = new Container();
$app->bind('SMysql', function () {
    return new DbMysql('host', 'name', 'pwd');
});
$app->bind('SRedis', function () {
    return new DbRedis('host', 'name', 'pwd');
});
$app->bind('controller', 'controller');
$controller = $app->make('controller');
$controller->action();
/**
 * 输出:
 * DbMysql::query
 * DbRedis::set
 */

使用接口了以后脚本执行正常。
首先容器绑定了接口SMysql和SRedis分别对应的闭包,绑定的关键字为接口名称,也就是说在容器中多次绑定一个接口只会绑定一个闭包一个类的实现,controller类的构造函数中声明了需要两个分别继承自SMysql接口和SRedis接口的类。容器中已经有了这两个接口的实现方式,所以直接调用闭包函数实例化类,然后将结果提供给controller类进行实例化。
本例中,我们仅仅make了controller类,也就是说我们只需要实例化controller类,而controller类依赖的DbMysql类和DbRedis类,IOC容器会自动帮我们实例化并注入。
本例中controller类的实例化很简单:

$app->bind('controller', 'controller');
$controller = $app->make('controller');

但是DbMysql和DbRedis就比较丑了:

$app->bind('SMysql', function () {
    return new DbMysql('host', 'name', 'pwd');
});
$app->bind('SRedis', function () {
    return new DbRedis('host', 'name', 'pwd');
});

其实是这两个类写的有问题,因为这两个类不是面对接口编程。但是这种自定义闭包函数的绑定非常方便,完全满足任何类的自由实例化。我们要做是依赖注入,那就全部使用接口来实现,看下一个例子。

示例七

interface MConfig
{
    public function getConfig();
}

class MysqlConfig implements MConfig
{
    public function getConfig()
    {
        // 获取配置
        return ['host', 'name', 'pwd'];
    }
}

interface RConfig
{
    public function getConfig();
}

class RedisConfig implements RConfig
{
    public function getConfig()
    {
        // 获取配置
        return ['host', 'name', 'pwd'];
    }
}

interface SMysql
{
    public function query();
}

class DbMysql implements SMysql
{
    public $config;

    public function __construct(MConfig $config)
    {
        $this->config = $config->getConfig();
        // do something
    }

    public function query()
    {
        echo __METHOD__ . PHP_EOL;
    }
}

interface SRedis
{
    public function Set();
}

class DbRedis implements SRedis
{
    public function __construct(RConfig $config)
    {
        $this->config = $config->getConfig();
        // do something
    }

    public function set()
    {
        echo __METHOD__ . PHP_EOL;
    }
}

class Controller
{
    public $mysql;
    public $redis;

    public function __construct(SMysql $mysql, SRedis $redis)
    {
        $this->mysql = $mysql;
        $this->redis = $redis;
    }

    public function action()
    {
        is_object($this->mysql) && $this->mysql->query();
        is_object($this->redis) && $this->redis->set();
    }
}

class Container
{

    public $bindings = [];

    public function bind($key, $value)
    {
        if (!$value instanceof Closure) {
            $this->bindings[$key] = $this->getClosure($value);
        } else {
            $this->bindings[$key] = $value;
        }
    }

    public function getClosure($value)
    {
        return function () use ($value) {
            return $this->build($value);
        };
    }

    public function make($key)
    {
        if (isset($this->bindings[$key])) {
            return $this->build($this->bindings[$key]);
        }
        return $this->build($key);
    }

    public function build($value)
    {
        if ($value instanceof Closure) {
            return $value();
        }
        // 实例化反射类
        $reflection = new ReflectionClass($value);
        // isInstantiable() 方法判断类是否可以实例化
        $isInstantiable = $reflection->isInstantiable();
        if ($isInstantiable) {
            // getConstructor() 方法获取类的构造函数,为NULL没有构造函数
            $constructor = $reflection->getConstructor();
            if (is_null($constructor)) {
                // 没有构造函数直接实例化对象返回
                return new $value;
            } else {
                // 有构造函数
                $params = $constructor->getParameters();
                if (empty($params)) {
                    // 构造函数没有参数,直接实例化对象返回
                    return new $value;
                } else {
                    $dependencies = [];
                    // 构造函数有参数
                    foreach ($params as $param) {
                        $dependency = $param->getClass();
                        if (is_null($dependency)) {
                            // 构造函数参数不为class,返回NULL
                            $dependencies[] = NULL;
                        } else {
                            // 类存在创建类实例
                            $dependencies[] = $this->make($param->getClass()->name);
                        }
                    }
                    return $reflection->newInstanceArgs($dependencies);
                }
            }
        }
        return null;
    }

}

$app = new Container();
$app->bind('MConfig', 'MysqlConfig');
$app->bind('RConfig', 'RedisConfig');
$app->bind('SMysql', 'DbMysql');
$app->bind('SRedis', 'DbRedis');
$app->bind('controller', 'Controller');
$controller = $app->make('controller');
$controller->action();
/**
 * 输出:
 * DbMysql::query
 * DbRedis::set
 */

是不是发现天下清静了许多,我们只需要实例化一个IOC容器,而后我们要使用到的所有类,它都能帮我们自动依赖注入。当然,这种实现是建立在组件针对接口编程上面的,否则就是示例六中的那种。

至此告一段落,一直想学习整理下IOC,总是这样那样的东西一直拖着,终于做到了。希望以后能有更多示例……

Phalcon 中文文档 一般都是直接看英文资料,大都能看得懂。但看到Phalcon框架如此优秀,在学习后就想大家分享,但发现国内的人几乎没有使用的,故想翻译一下,一旦翻译才发现读懂译出一篇好文章真的不太一样。 故前一期翻译的部分章节有点生硬,等有空的时候再回头重译吧,后面的一部分也是以英文文档为基础,但并不再是逐句翻译了。 09年左右,大量的框架出现,我看过的框架不下20种,最先看到的可能就是php.MVC了,这是一个按照struts 1x编写的,只不过同时加载的类库太多了,效率不高而且不太完善。 后来稍有名的包括 cakephp, Symfony, Akelos, Prado, Kohana等,最近几年流行的就是 zf, yii, ci等,当然还有国内几个比较有名的框架,如fleaphp, thinkphp等。 在上面的一些框架中,我比较感冒的还是ci,yii,thinkphp等。ci,thinkphp够简单,速度也不错。yii是生活在国外的华人开发,功能够全而强大,速度也不错,国内的应用也不少。 一直不太喜欢zf,记得几年前就同行朋友聊天的时候说,像ZEND公司完全可以用C语言开发出一个扩展来,这样效率会高得多,为毛非得用PHP开发呢,事实被我验证了,但开发扩展的不是ZEND公司,而是国内一个PHP大鸟,人称鸟哥。这个框架就是非常出名的YAF,因此YAF扩展是我必装的扩展之一。同时这也是我发现的第一个C语言写的扩展框架。 但YAF的缺点是,功能非常不完善,在我看来只是简单实现了MVC结构及路由,分发等功能,像一些ORM之类的功能完全没有开发,作者好像也没有开发的意思:) 后来就发现了Phalcon,一看文档就爱上了她,功能,速度等都是我想要的,我花了一周时间看文档学习她,并在一个下午的过程中,发现了文档中的三个错误并提交了这些错误:),我决定为完善它也贡献一点自己的力量。 本文档的中文地址存放在 http://phalcon.5iunix.net Github上的地址为: https://github.com/netstu/phalcondocs ,您如果发现有些地方译的有些操蛋,烦请你fork它,并完善她。
iphone5s拆机方法图解-多图 独家:iphone5s拆机方法图解--共37图 Step 1 — iPhone 5s Teardown • [size=1em]An iPhone release means a trip to the future—the iFixit teardown crew has traveled 17 hours forward in time to get the iPhone 5s early. • [size=1em]We want to send out a big thanks to our good friends at MacFixit Australia for letting us use their office in Melbourne for the teardown. They stock Mac and iPhone upgrades/accessories, and also carry ouriFixit toolkits. o [size=1em]To cover all our bases, we confirmed with our best linguists that the 5s upside-down is still the 5s. • [size=1em]Speaking of toolkits, for this teardown, we'll be using iFixit's brand-new Pro Tech Screwdriver Set. Step 2 • [size=1em]As we ready ourselves to delve into the delightful innards of the 5s, let's check out some of its tech specs: o [size=1em]Apple A7 processor with 64-bit architecture o [size=1em]M7 motion co-processor o [size=1em]16, 32, or 64 GB Storage o [size=1em]4-inch retina display with 326 ppi o [size=1em]8 MP iSight camera (with larger 1.5μ pixels) and a 1.2MP FaceTime camera. o [size=1em]Fingerprint identity sensor built into the home button o [size=1em]Available in three different colors: space gray, silver, and gooooooold (or as we call them, Not-at-all-the-Color-of-Space, Second Place Medal, and Bling!). Step 3 • [size=1em]Apple continues the everlasting trend of locking users out with pentalobular screws. Luckily, we came prepared. We whip out our trusty iPhone 5 Liberation Kit, and to our pleasant surprise, it works! • [size=1em]Unfortunately, we are ill-equipped in the color department, as we only have silver and black replacement Phillips screws. o [size=1em]We are currently involved in heavy lobbying to our product designers to create 14k gold replacement screws. They'll be $50 each and strip the first time you try to unscrew them, so they will be perfect for the iPhone. Stay posted. • [size=1em]With our iPhone 5s sufficiently liberated, it reminds us of another polka-dotted iPhone teardown coming in the near future… Step 4 • [size=1em]We're done screwing around; it's time to get this baby open! Just like last year, we enlist the help of a suction cup to free the display assembly from the rear casing. • [size=1em]Unlike last year, we make use of some gentle spudgering, just in case… Step 5 • [size=1em]Our careful spudgering paid off. At the bottom of the phone, a cable connects the Touch ID sensor in the home button to the Lightning port assembly. o [size=1em]This adds a small element of danger to disassembly, as pulling too hard on the suction cup could cause accidental damage to the cable. • [size=1em]We survive this first booby trap and swiftly disconnect the Touch ID cable connector with the help of a spudger. • [size=1em]Alas, our first peek at the internal layout of the 5s. Comparing it to the iPhone 5, we spot very few differences, the main one being the lack of a battery removal pull-tab. Step 6 • [size=1em]With our favorite screwdriver set, we remove a few metal connector covers and embark on the epic battle of battery removal. • [size=1em]The missing battery pull-tab, though seemingly innocuous, indicates a bigger problem for battery repair: glue. • [size=1em]Perhaps the "s" in 5s stands for "stuck," as in "this battery is stuck in with a lot of glue," or "I hope you didn't want to replace your battery—you're going to be stuck with this one." • [size=1em]While we'd love a tool-less battery removal as we've seen in other phones, we settle for thermal battery removal via an iOpener. • [size=1em]Holy adhesive! It appears Apple ditched the minimal adhesive in the iPhone 5 in favor of those two huge white runways of adhesive holding the 5s(tuck) battery in place. Step 7 • [size=1em]The 5s has a claimed 10 hours of talk time on 3G, but there are rumbles that iOS 7 isn't doing you any favors. • [size=1em]The gold unit from Desay Battery Co., Ltd in Huizhou, China sports a 3.8V - 5.92Wh - 1560mAh battery. Comparatively: o [size=1em]iPhone 5: 3.8 V - 1440 mAh - 5.45 Wh. Talk time: Up to 8 hours on 3G. Standby time: Up to 225 hours. o [size=1em]Samsung Galaxy S4: 3.8 V - 2600 mAh - 9.88 Wh. Talk time: up to 7 hours. Standby time: Up to 300 hours. o [size=1em]Motorola Moto X: 3.8 V - 2200 mAh - 8.4 Wh. 24 hours of "mixed usage." • [size=1em]It appears different units sport different battery manufacturers; our "space-gray" spare (right) comes to us from Simplo Technology Inc. Step 8 • [size=1em]With the battery safely removed, we turn to the next step in our disassembly journey: removing the(unchanged) 326 ppi Retina display assembly. • [size=1em]A few flicks of a spudger to disconnect the FaceTime camera, digitizer, and LCD cables, and the display is free. o [size=1em]Looking for some tech specs on the display? Well look no further! In fact, just look backwards…to the iPhone 5. Despite the trend in almost every other smartphone release, the iPhone 5s display is no bigger, better, or badder than the 5. Step 9 • [size=1em]We quickly extract the home button and Touch ID, Apple's new fingerprint scanner. Time to dust for prints! o [size=1em]A CMOS chip, the Touch ID is essentially a bunch of very small capacitors that creates an "image" of the ridges on your finger. • [size=1em]The sensor technology, developed by AuthenTecand bought by Apple a year ago, reportedly stores your fingerprints locally, so giving your iPhone the finger will not make it all the way back to Cupertino. • [size=1em]We worry about how well the sapphire crystal covering the sensor can protect it from degrading over time like most CMOS fingerprint sensors. If not, it could become a ticking time bomb, just like that super-glued battery. Step 10 • [size=1em]We uncover the iSight camera. • [size=1em]The back of the iSight camera is labeled DNL333 41WGRF 4W61W. • [size=1em]According to our good friend Jim Morrison, Vice President of the Technology Analysis Group atChipworks, "the DNL markings are consistent with the markings on the camera modules housing the Sony IMX145 we saw in the iPhone 4s and on the iPhone 5. The marks on the side of the module are different, but our industry insiders tell us this is Sony's again" • [size=1em]As Apple has stated the pixel pitch on this camera is 1.5 μ, this sensor should not be the IMX145, but a newer variant. • [size=1em]The bottom of the camera is labeled AW32 65BD 4511 b763. Step 11 • [size=1em]For those of us counting steps and comparing with last year, we're unsurprisingly right on par. • [size=1em]A great example of Apple's iterative design, the 5s shows some streamlining and optimization in its internal construction. • [size=1em]Gone are those silly antenna interconnect cables, leaving one less thing to break or get accidentally disconnected. o [size=1em]If only they had decided to move that antenna connector from the bottom of the logic board to the top... Step 12 • [size=1em]Looks like we found a Murata 339S0205 Wi-Fi module (based on the Broadcom BCM4334, according to Chipworks). • [size=1em]Again comparing our 16 and 64 GB models: o [size=1em]It seems that the Murata IC is the same between both iPhone 5s'. o [size=1em]The design of both logic boards may be identical, but slight differences in markings (e.g. 94V-0 on the rightmost, nonexistent on the leftmost) may indicate that Apple is manufacturing the 5s logic boards at multiple locations. Step 13 ¶ • [size=1em]Open ses-EMI! Behold, IC treasures identified: o [size=1em]SK Hynix H2JTDG8UD3MBR 128 Gb (16 GB) NAND Flash o [size=1em]Qualcomm PM8018 RF power management IC o [size=1em]TriQuint TQM6M6224 o [size=1em]Apple 338S1216 o [size=1em]Broadcom BCM5976 touchscreen controller o [size=1em]Texas Instruments 37C64G1 o [size=1em]Skyworks 77810 Step 14 • [size=1em]More ICs! o [size=1em]Skyworks 77355 o [size=1em]Avago A790720 o [size=1em]Avago A7900 o [size=1em]Apple 338S120L • [size=1em]A super-awesome thanks to the Chipworks team for helping us decode and discern these delightful devices! Step 15 • [size=1em]Turning our attention to the backside of the logic board: o [size=1em]Apple A7 APL0698 SoC (based on thisMacRumors post, the markings F8164A1PD indicate the RAM is likely 1GB) o [size=1em]Qualcomm MDM9615M LTE Modem o [size=1em]Qualcomm WTR1605LLTE/HSPA+/CDMA2K/TDSCDMA/EDGE/GPS transceiver. • [size=1em]As we search for a much-anticipated M7 coprocessor, we begin to wonder if it actually is a separate IC, or if it is additional functionality built into the A7. o [size=1em]Maybe the "M" stands for "magical," the M7 is invisible, and Apple does use pixie dust to hold the device together. Or perhaps the "M" stands for "marketing"… o [size=1em]Update: the M7 has been found! • [size=1em]Our A7 was fabbed in July. Step 16 • [size=1em]It's time to investigate the new kid on the block, and it's fly like an A7. Along with the fingerprint sensor, the A7 is a major enticement for consumers to pick the 5s over the 5c. • [size=1em]The A7 is advertised as providing twice the performance of the 5 (and 5c)'s A6 processor. o [size=1em]The switch to the A7 marks the first use of a 64-bit processor in a smartphone. Based on AnandTech's review, it seems that the bulk of the A7's performance gains do not come from any advantages inherent to a 64-bit architecture, but rather from the switch from the outdated ARMv7 instruction set to the newly-designed ARMv8. o [size=1em]The modern ARMv8 instruction set was designed for a 64-bit architecture. It does away with the legacy support of the last 20 years, which increases efficiency, improving performance without sacrificing battery life. • [size=1em]We'll have to wait until we get inside the chip to find out who manufactured it. Step 17 • [size=1em]Time for your close-up, selfie cam! • [size=1em]A few screws hold the 1.2MP FaceTime camera in place. • [size=1em]While the updated pixel size in the iSight camera may get a lot of attention, DIY paparazzi is what bling iPhones are all about. Step 18 • [size=1em]The lower peripherals on the 5s look very similar to those in the 5, though the speaker assembly comes out with slightly more ease in this iteration. • [size=1em]With the speaker assembly out, the headphone jack/microphone/Lightning connector assembly comes out easily. o [size=1em]As with previous generations, you will have to replace multiple components at once, since the design is not modular. Step 19 • [size=1em]We find another hardware update: the new dual flash. • [size=1em]White and amber LEDs sit by the camera to balance the flash-induced ghostly tones of night-life photography. Step 20 • [size=1em]iPhone 5s Repairability: 6 out of 10 (10 is easiest to repair) • [size=1em]Just like in the iPhone 5, the display assembly is the first component out of the phone, simplifying screen replacements. • [size=1em]The battery is still fairly easy to access, even though it's not technically "user replaceable." • [size=1em]The battery has lost the 5's convenient pull tab, and gained more resilient adhesive—it now requires heat and prying to remove. • [size=1em]The fingerprint sensor cable could be easily ripped out of its socket if a user is not careful while opening the phone. • [size=1em]The iPhone 5s still uses Pentalobe screws on the exterior, making the 5s difficult to open. • [size=1em]The front glass, digitizer, and LCD are all one component, thereby increasing cost of repair.
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值