mirror of
https://github.com/codeigniter4/CodeIgniter4.git
synced 2025-02-20 11:44:28 +08:00
656 lines
42 KiB
HTML
656 lines
42 KiB
HTML
|
||
|
||
<!DOCTYPE html>
|
||
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
|
||
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
|
||
<head>
|
||
<meta charset="utf-8">
|
||
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
||
<title>Working With Entities — CodeIgniter4 4.0.0-beta.2 documentation</title>
|
||
|
||
|
||
|
||
|
||
<link rel="shortcut icon" href="../_static/ci-icon.ico"/>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<link rel="stylesheet" href="../_static/css/citheme.css" type="text/css" />
|
||
|
||
|
||
|
||
|
||
|
||
<link rel="top" title="CodeIgniter4 4.0.0-beta.2 documentation" href="../index.html"/>
|
||
<link rel="up" title="Modeling Data" href="index.html"/>
|
||
<link rel="next" title="Managing Databases" href="../dbmgmt/index.html"/>
|
||
<link rel="prev" title="Using CodeIgniter’s Model" href="model.html"/>
|
||
|
||
|
||
<script src="../_static/js/modernizr.min.js"></script>
|
||
|
||
</head>
|
||
|
||
<body class="wy-body-for-nav" role="document">
|
||
|
||
|
||
<div class="wy-grid-for-nav">
|
||
|
||
|
||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
||
<div class="wy-side-scroll">
|
||
<div class="wy-side-nav-search">
|
||
|
||
|
||
|
||
<a href="../index.html" class="icon icon-home"> CodeIgniter4
|
||
|
||
|
||
|
||
</a>
|
||
|
||
|
||
|
||
|
||
<div role="search">
|
||
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
|
||
<input type="text" name="q" placeholder="Search docs" />
|
||
<input type="hidden" name="check_keywords" value="yes" />
|
||
<input type="hidden" name="area" value="default" />
|
||
</form>
|
||
</div>
|
||
|
||
|
||
</div>
|
||
|
||
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<ul>
|
||
<li class="toctree-l1"><a class="reference internal" href="../intro/index.html">Welcome to CodeIgniter4</a></li>
|
||
</ul>
|
||
<ul>
|
||
<li class="toctree-l1"><a class="reference internal" href="../installation/index.html">Installation</a></li>
|
||
</ul>
|
||
<ul>
|
||
<li class="toctree-l1"><a class="reference internal" href="../tutorial/index.html">Tutorial</a></li>
|
||
</ul>
|
||
<ul>
|
||
<li class="toctree-l1"><a class="reference internal" href="../concepts/index.html">CodeIgniter4 Overview</a></li>
|
||
</ul>
|
||
<ul>
|
||
<li class="toctree-l1"><a class="reference internal" href="../general/index.html">General Topics</a></li>
|
||
</ul>
|
||
<ul>
|
||
<li class="toctree-l1"><a class="reference internal" href="../incoming/index.html">Controllers and Routing</a></li>
|
||
</ul>
|
||
<ul>
|
||
<li class="toctree-l1"><a class="reference internal" href="../outgoing/index.html">Building Responses</a></li>
|
||
</ul>
|
||
<ul>
|
||
<li class="toctree-l1"><a class="reference internal" href="../database/index.html">Working With Databases</a></li>
|
||
</ul>
|
||
<ul class="current">
|
||
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Modeling Data</a><ul class="current">
|
||
<li class="toctree-l2"><a class="reference internal" href="model.html">Using CodeIgniter’s Model</a></li>
|
||
<li class="toctree-l2 current"><a class="current reference internal" href="#">Using Entity Classes</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<ul>
|
||
<li class="toctree-l1"><a class="reference internal" href="../dbmgmt/index.html">Managing Databases</a></li>
|
||
</ul>
|
||
<ul>
|
||
<li class="toctree-l1"><a class="reference internal" href="../libraries/index.html">Library Reference</a></li>
|
||
</ul>
|
||
<ul>
|
||
<li class="toctree-l1"><a class="reference internal" href="../helpers/index.html">Helpers</a></li>
|
||
</ul>
|
||
<ul>
|
||
<li class="toctree-l1"><a class="reference internal" href="../testing/index.html">Testing</a></li>
|
||
</ul>
|
||
<ul>
|
||
<li class="toctree-l1"><a class="reference internal" href="../cli/index.html">Command Line Usage</a></li>
|
||
</ul>
|
||
<ul>
|
||
<li class="toctree-l1"><a class="reference internal" href="../extending/index.html">Extending CodeIgniter</a></li>
|
||
</ul>
|
||
<ul>
|
||
<li class="toctree-l1"><a class="reference internal" href="../license.html">The MIT License (MIT)</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="../changelogs/index.html">Change Logs</a></li>
|
||
</ul>
|
||
|
||
|
||
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
|
||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
|
||
|
||
|
||
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
|
||
|
||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||
<a href="../index.html">CodeIgniter4</a>
|
||
|
||
</nav>
|
||
|
||
|
||
|
||
<div class="wy-nav-content">
|
||
<div class="rst-content">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<div role="navigation" aria-label="breadcrumbs navigation">
|
||
|
||
<ul class="wy-breadcrumbs">
|
||
|
||
<li><a href="../index.html">Docs</a> »</li>
|
||
|
||
<li><a href="index.html">Modeling Data</a> »</li>
|
||
|
||
<li>Working With Entities</li>
|
||
|
||
|
||
<li class="wy-breadcrumbs-aside">
|
||
|
||
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
|
||
|
||
<hr/>
|
||
</div>
|
||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||
<div itemprop="articleBody">
|
||
|
||
<div class="section" id="working-with-entities">
|
||
<h1>Working With Entities<a class="headerlink" href="#working-with-entities" title="Permalink to this headline">¶</a></h1>
|
||
<p>CodeIgniter supports Entity classes as a first-class citizen in it’s database layer, while keeping
|
||
them completely optional to use. They are commonly used as part of the Repository pattern, but can
|
||
be used directly with the <a class="reference internal" href="model.html"><span class="doc">Model</span></a> if that fits your needs better.</p>
|
||
<div class="contents local topic" id="contents">
|
||
<ul class="simple">
|
||
<li><a class="reference internal" href="#entity-usage" id="id1">Entity Usage</a><ul>
|
||
<li><a class="reference internal" href="#create-the-entity-class" id="id2">Create the Entity Class</a></li>
|
||
<li><a class="reference internal" href="#create-the-model" id="id3">Create the Model</a></li>
|
||
<li><a class="reference internal" href="#working-with-the-entity-class" id="id4">Working With the Entity Class</a></li>
|
||
<li><a class="reference internal" href="#filling-properties-quickly" id="id5">Filling Properties Quickly</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#handling-business-logic" id="id6">Handling Business Logic</a></li>
|
||
<li><a class="reference internal" href="#data-mapping" id="id7">Data Mapping</a></li>
|
||
<li><a class="reference internal" href="#mutators" id="id8">Mutators</a><ul>
|
||
<li><a class="reference internal" href="#date-mutators" id="id9">Date Mutators</a></li>
|
||
<li><a class="reference internal" href="#property-casting" id="id10">Property Casting</a></li>
|
||
<li><a class="reference internal" href="#array-json-casting" id="id11">Array/Json Casting</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div class="section" id="entity-usage">
|
||
<h2><a class="toc-backref" href="#id1">Entity Usage</a><a class="headerlink" href="#entity-usage" title="Permalink to this headline">¶</a></h2>
|
||
<p>At its core, an Entity class is simply a class that represents a single database row. It has class properties
|
||
to represent the database columns, and provides any additional methods to implement the business logic for
|
||
that row. The core feature, though, is that it doesn’t know anything about how to persist itself. That’s the
|
||
responsibility of the model or the repository class. That way, if anything changes on how you need to save the
|
||
object, you don’t have to change how that object is used throughout the application. This makes it possible to
|
||
use JSON or XML files to store the objects during a rapid prototyping stage, and then easily switch to a
|
||
database when you’ve proven the concept works.</p>
|
||
<p>Let’s walk through a very simple User Entity and how we’d work with it to help make things clear.</p>
|
||
<p>Assume you have a database table named <code class="docutils literal"><span class="pre">users</span></code> that has the following schema:</p>
|
||
<div class="highlight-ci"><div class="highlight"><pre><span></span><span class="nx">id</span> <span class="o">-</span> <span class="nx">integer</span>
|
||
<span class="nx">username</span> <span class="o">-</span> <span class="nx">string</span>
|
||
<span class="nx">email</span> <span class="o">-</span> <span class="nx">string</span>
|
||
<span class="nx">password</span> <span class="o">-</span> <span class="nx">string</span>
|
||
<span class="nx">created_at</span> <span class="o">-</span> <span class="nx">datetime</span>
|
||
</pre></div>
|
||
</div>
|
||
<div class="section" id="create-the-entity-class">
|
||
<h3><a class="toc-backref" href="#id2">Create the Entity Class</a><a class="headerlink" href="#create-the-entity-class" title="Permalink to this headline">¶</a></h3>
|
||
<p>Now create a new Entity class. Since there’s no default location to store these classes, and it doesn’t fit
|
||
in with the existing directory structure, create a new directory at <strong>app/Entities</strong>. Create the
|
||
Entity itself at <strong>app/Entities/User.php</strong>.</p>
|
||
<div class="highlight-ci"><div class="highlight"><pre><span></span><span class="o"><?</span><span class="nx">php</span> <span class="k">namespace</span> <span class="nx">App\Entities</span><span class="p">;</span>
|
||
|
||
<span class="k">use</span> <span class="nx">CodeIgniter\Entity</span><span class="p">;</span>
|
||
|
||
<span class="k">class</span> <span class="nc">User</span> <span class="k">extends</span> <span class="nx">Entity</span>
|
||
<span class="p">{</span>
|
||
<span class="k">protected</span> <span class="nv">$id</span><span class="p">;</span>
|
||
<span class="k">protected</span> <span class="nv">$username</span><span class="p">;</span>
|
||
<span class="k">protected</span> <span class="nv">$email</span><span class="p">;</span>
|
||
<span class="k">protected</span> <span class="nv">$password</span><span class="p">;</span>
|
||
<span class="k">protected</span> <span class="nv">$created_at</span><span class="p">;</span>
|
||
<span class="k">protected</span> <span class="nv">$updated_at</span><span class="p">;</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>At its simplest, this is all you need to do, though we’ll make it more useful in a minute. Note that all of the
|
||
database columns are represented in the Entity. This is required for the Model to populate the fields.</p>
|
||
</div>
|
||
<div class="section" id="create-the-model">
|
||
<h3><a class="toc-backref" href="#id3">Create the Model</a><a class="headerlink" href="#create-the-model" title="Permalink to this headline">¶</a></h3>
|
||
<p>Create the model first at <strong>app/Models/UserModel.php</strong> so that we can interact with it:</p>
|
||
<div class="highlight-ci"><div class="highlight"><pre><span></span><span class="o"><?</span><span class="nx">php</span> <span class="k">namespace</span> <span class="nx">App\Models</span><span class="p">;</span>
|
||
|
||
<span class="k">use</span> <span class="nx">CodeIgniter\Model</span><span class="p">;</span>
|
||
|
||
<span class="k">class</span> <span class="nc">UserModel</span> <span class="k">extends</span> <span class="nx">Model</span>
|
||
<span class="p">{</span>
|
||
<span class="k">protected</span> <span class="nv">$table</span> <span class="o">=</span> <span class="s1">'users'</span><span class="p">;</span>
|
||
<span class="k">protected</span> <span class="nv">$allowedFields</span> <span class="o">=</span> <span class="p">[</span>
|
||
<span class="s1">'username'</span><span class="p">,</span> <span class="s1">'email'</span><span class="p">,</span> <span class="s1">'password'</span>
|
||
<span class="p">];</span>
|
||
<span class="k">protected</span> <span class="nv">$returnType</span> <span class="o">=</span> <span class="s1">'App\Entities\User'</span><span class="p">;</span>
|
||
<span class="k">protected</span> <span class="nv">$useTimestamps</span> <span class="o">=</span> <span class="k">true</span><span class="p">;</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The model uses the <code class="docutils literal"><span class="pre">users</span></code> table in the database for all of its activities. We’ve set the <code class="docutils literal"><span class="pre">$allowedFields</span></code> property
|
||
to include all of the fields that we want outside classes to change. The <code class="docutils literal"><span class="pre">id</span></code>, <code class="docutils literal"><span class="pre">created_at</span></code>, and <code class="docutils literal"><span class="pre">updated_at</span></code> fields
|
||
are handled automatically by the class or the database, so we don’t want to change those. Finally, we’ve set our Entity
|
||
class as the <code class="docutils literal"><span class="pre">$returnType</span></code>. This ensures that all methods on the model that return rows from the database will return
|
||
instances of our User Entity class instead of an object or array like normal.</p>
|
||
</div>
|
||
<div class="section" id="working-with-the-entity-class">
|
||
<h3><a class="toc-backref" href="#id4">Working With the Entity Class</a><a class="headerlink" href="#working-with-the-entity-class" title="Permalink to this headline">¶</a></h3>
|
||
<p>Now that all of the pieces are in place, you would work with the Entity class as you would any other class:</p>
|
||
<div class="highlight-ci"><div class="highlight"><pre><span></span><span class="nv">$user</span> <span class="o">=</span> <span class="nv">$userModel</span><span class="o">-></span><span class="na">find</span><span class="p">(</span><span class="nv">$id</span><span class="p">);</span>
|
||
|
||
<span class="c1">// Display</span>
|
||
<span class="k">echo</span> <span class="nv">$user</span><span class="o">-></span><span class="na">username</span><span class="p">;</span>
|
||
<span class="k">echo</span> <span class="nv">$user</span><span class="o">-></span><span class="na">email</span><span class="p">;</span>
|
||
|
||
<span class="c1">// Updating</span>
|
||
<span class="nb">unset</span><span class="p">(</span><span class="nv">$user</span><span class="o">-></span><span class="na">username</span><span class="p">);</span>
|
||
<span class="k">if</span> <span class="p">(</span><span class="o">!</span> <span class="nb">isset</span><span class="p">(</span><span class="nv">$user</span><span class="o">-></span><span class="na">username</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="nv">$user</span><span class="o">-></span><span class="na">username</span> <span class="o">=</span> <span class="s1">'something new'</span><span class="p">;</span>
|
||
<span class="p">}</span>
|
||
<span class="nv">$userModel</span><span class="o">-></span><span class="na">save</span><span class="p">(</span><span class="nv">$user</span><span class="p">);</span>
|
||
|
||
<span class="c1">// Create</span>
|
||
<span class="nv">$user</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">App\Entities\User</span><span class="p">();</span>
|
||
<span class="nv">$user</span><span class="o">-></span><span class="na">username</span> <span class="o">=</span> <span class="s1">'foo'</span><span class="p">;</span>
|
||
<span class="nv">$user</span><span class="o">-></span><span class="na">email</span> <span class="o">=</span> <span class="s1">'foo@example.com'</span><span class="p">;</span>
|
||
<span class="nv">$userModel</span><span class="o">-></span><span class="na">save</span><span class="p">(</span><span class="nv">$user</span><span class="p">);</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>You may have noticed that the User class has all of the properties as <strong>protected</strong> not <strong>public</strong>, but you can still
|
||
access them as if they were public properties. The base class, <strong>CodeIgniterEntity</strong>, takes care of this for you, as
|
||
well as providing the ability to check the properties with <strong>isset()</strong>, or <strong>unset()</strong> the property.</p>
|
||
<p>When the User is passed to the model’s <strong>save()</strong> method, it automatically takes care of reading the protected properties
|
||
and saving any changes to columns listed in the model’s <strong>$allowedFields</strong> property. It also knows whether to create
|
||
a new row, or update an existing one.</p>
|
||
</div>
|
||
<div class="section" id="filling-properties-quickly">
|
||
<h3><a class="toc-backref" href="#id5">Filling Properties Quickly</a><a class="headerlink" href="#filling-properties-quickly" title="Permalink to this headline">¶</a></h3>
|
||
<p>The Entity class also provides a method, <code class="docutils literal"><span class="pre">fill()</span></code> that allows you to shove an array of key/value pairs into the class
|
||
and populate the class properties. Only properties that already exist in the class can be populated in this way.</p>
|
||
<div class="highlight-ci"><div class="highlight"><pre><span></span><span class="nv">$data</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-></span><span class="na">request</span><span class="o">-></span><span class="na">getPost</span><span class="p">();</span>
|
||
|
||
<span class="nv">$user</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">App\Entities\User</span><span class="p">();</span>
|
||
<span class="nv">$user</span><span class="o">-></span><span class="na">fill</span><span class="p">(</span><span class="nv">$data</span><span class="p">);</span>
|
||
<span class="nv">$userModel</span><span class="o">-></span><span class="na">save</span><span class="p">(</span><span class="nv">$user</span><span class="p">);</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="handling-business-logic">
|
||
<h2><a class="toc-backref" href="#id6">Handling Business Logic</a><a class="headerlink" href="#handling-business-logic" title="Permalink to this headline">¶</a></h2>
|
||
<p>While the examples above are convenient, they don’t help enforce any business logic. The base Entity class implements
|
||
some smart <code class="docutils literal"><span class="pre">__get()</span></code> and <code class="docutils literal"><span class="pre">__set()</span></code> methods that will check for special methods and use those instead of using
|
||
the class properties directly, allowing you to enforce any business logic or data conversion that you need.</p>
|
||
<p>Here’s an updated User entity to provide some examples of how this could be used:</p>
|
||
<div class="highlight-ci"><div class="highlight"><pre><span></span><span class="o"><?</span><span class="nx">php</span> <span class="k">namespace</span> <span class="nx">App\Entities</span><span class="p">;</span>
|
||
|
||
<span class="k">use</span> <span class="nx">CodeIgniter\Entity</span><span class="p">;</span>
|
||
<span class="k">use</span> <span class="nx">CodeIgniter\I18n\Time</span><span class="p">;</span>
|
||
|
||
<span class="k">class</span> <span class="nc">User</span> <span class="k">extends</span> <span class="nx">Entity</span>
|
||
<span class="p">{</span>
|
||
<span class="k">protected</span> <span class="nv">$id</span><span class="p">;</span>
|
||
<span class="k">protected</span> <span class="nv">$username</span><span class="p">;</span>
|
||
<span class="k">protected</span> <span class="nv">$email</span><span class="p">;</span>
|
||
<span class="k">protected</span> <span class="nv">$password</span><span class="p">;</span>
|
||
<span class="k">protected</span> <span class="nv">$created_at</span><span class="p">;</span>
|
||
<span class="k">protected</span> <span class="nv">$updated_at</span><span class="p">;</span>
|
||
|
||
<span class="k">public</span> <span class="k">function</span> <span class="nf">setPassword</span><span class="p">(</span><span class="nx">string</span> <span class="nv">$pass</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="nv">$this</span><span class="o">-></span><span class="na">password</span> <span class="o">=</span> <span class="nb">password_hash</span><span class="p">(</span><span class="nv">$pass</span><span class="p">,</span> <span class="nx">PASSWORD_BCRYPT</span><span class="p">);</span>
|
||
|
||
<span class="k">return</span> <span class="nv">$this</span><span class="p">;</span>
|
||
<span class="p">}</span>
|
||
|
||
<span class="k">public</span> <span class="k">function</span> <span class="nf">setCreatedAt</span><span class="p">(</span><span class="nx">string</span> <span class="nv">$dateString</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="nv">$this</span><span class="o">-></span><span class="na">created_at</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Time</span><span class="p">(</span><span class="nv">$dateString</span><span class="p">,</span> <span class="s1">'UTC'</span><span class="p">);</span>
|
||
|
||
<span class="k">return</span> <span class="nv">$this</span><span class="p">;</span>
|
||
<span class="p">}</span>
|
||
|
||
<span class="k">public</span> <span class="k">function</span> <span class="nf">getCreatedAt</span><span class="p">(</span><span class="nx">string</span> <span class="nv">$format</span> <span class="o">=</span> <span class="s1">'Y-m-d H:i:s'</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="c1">// Convert to CodeIgniter\I18n\Time object</span>
|
||
<span class="nv">$this</span><span class="o">-></span><span class="na">created_at</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-></span><span class="na">mutateDate</span><span class="p">(</span><span class="nv">$this</span><span class="o">-></span><span class="na">created_at</span><span class="p">);</span>
|
||
|
||
<span class="nv">$timezone</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-></span><span class="na">timezone</span> <span class="o">??</span> <span class="nx">app_timezone</span><span class="p">();</span>
|
||
|
||
<span class="nv">$this</span><span class="o">-></span><span class="na">created_at</span><span class="o">-></span><span class="na">setTimezone</span><span class="p">(</span><span class="nv">$timezone</span><span class="p">);</span>
|
||
|
||
<span class="k">return</span> <span class="nv">$this</span><span class="o">-></span><span class="na">created_at</span><span class="o">-></span><span class="na">format</span><span class="p">(</span><span class="nv">$format</span><span class="p">);</span>
|
||
<span class="p">}</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The first thing to notice is the name of the methods we’ve added. For each one, the class expects the snake_case
|
||
column name to be converted into PascalCase, and prefixed with either <code class="docutils literal"><span class="pre">set</span></code> or <code class="docutils literal"><span class="pre">get</span></code>. These methods will then
|
||
be automatically called whenever you set or retrieve the class property using the direct syntax (i.e. $user->email).
|
||
The methods do not need to be public unless you want them accessed from other classes. For example, the <code class="docutils literal"><span class="pre">created_at</span></code>
|
||
class property will be accessed through the <code class="docutils literal"><span class="pre">setCreatedAt()</span></code> and <code class="docutils literal"><span class="pre">getCreatedAt()</span></code> methods.</p>
|
||
<div class="admonition note">
|
||
<p class="first admonition-title">Note</p>
|
||
<p class="last">This only works when trying to access the properties from outside of the track. Any methods internal to the
|
||
class must call the <code class="docutils literal"><span class="pre">setX()</span></code> and <code class="docutils literal"><span class="pre">getX()</span></code> methods directly.</p>
|
||
</div>
|
||
<p>In the <code class="docutils literal"><span class="pre">setPassword()</span></code> method we ensure that the password is always hashed.</p>
|
||
<p>In <code class="docutils literal"><span class="pre">setCreatedAt()</span></code> we convert the string we receive from the model into a DateTime object, ensuring that our timezone
|
||
is UTC so we can easily convert the viewer’s current timezone. In <code class="docutils literal"><span class="pre">getCreatedAt()</span></code>, it converts the time to
|
||
a formatted string in the application’s current timezone.</p>
|
||
<p>While fairly simple, these examples show that using Entity classes can provide a very flexible way to enforce
|
||
business logic and create objects that are pleasant to use.</p>
|
||
<div class="highlight-ci"><div class="highlight"><pre><span></span><span class="c1">// Auto-hash the password - both do the same thing</span>
|
||
<span class="nv">$user</span><span class="o">-></span><span class="na">password</span> <span class="o">=</span> <span class="s1">'my great password'</span><span class="p">;</span>
|
||
<span class="nv">$user</span><span class="o">-></span><span class="na">setPassword</span><span class="p">(</span><span class="s1">'my great password'</span><span class="p">);</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="data-mapping">
|
||
<h2><a class="toc-backref" href="#id7">Data Mapping</a><a class="headerlink" href="#data-mapping" title="Permalink to this headline">¶</a></h2>
|
||
<p>At many points in your career, you will run into situations where the use of an application has changed and the
|
||
original column names in the database no longer make sense. Or you find that your coding style prefers camelCase
|
||
class properties, but your database schema required snake_case names. These situations can be easily handled
|
||
with the Entity class’ data mapping features.</p>
|
||
<p>As an example, imagine you have the simplified User Entity that is used throughout your application:</p>
|
||
<div class="highlight-ci"><div class="highlight"><pre><span></span><span class="o"><?</span><span class="nx">php</span> <span class="k">namespace</span> <span class="nx">App\Entities</span><span class="p">;</span>
|
||
|
||
<span class="k">use</span> <span class="nx">CodeIgniter\Entity</span><span class="p">;</span>
|
||
|
||
<span class="k">class</span> <span class="nc">User</span> <span class="k">extends</span> <span class="nx">Entity</span>
|
||
<span class="p">{</span>
|
||
<span class="k">protected</span> <span class="nv">$id</span><span class="p">;</span>
|
||
<span class="k">protected</span> <span class="nv">$name</span><span class="p">;</span> <span class="c1">// Represents a username</span>
|
||
<span class="k">protected</span> <span class="nv">$email</span><span class="p">;</span>
|
||
<span class="k">protected</span> <span class="nv">$password</span><span class="p">;</span>
|
||
<span class="k">protected</span> <span class="nv">$created_at</span><span class="p">;</span>
|
||
<span class="k">protected</span> <span class="nv">$updated_at</span><span class="p">;</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Your boss comes to you and says that no one uses usernames anymore, so you’re switching to just use emails for login.
|
||
But they do want to personalize the application a bit, so they want you to change the name field to represent a user’s
|
||
full name now, not their username like it does currently. To keep things tidy and ensure things continue making sense
|
||
in the database you whip up a migration to rename the <cite>name</cite> field to <cite>full_name</cite> for clarity.</p>
|
||
<p>Ignoring how contrived this example is, we now have two choices on how to fix the User class. We could modify the class
|
||
property from <code class="docutils literal"><span class="pre">$name</span></code> to <code class="docutils literal"><span class="pre">$full_name</span></code>, but that would require changes throughout the application. Instead, we can
|
||
simply map the <code class="docutils literal"><span class="pre">full_name</span></code> column in the database to the <code class="docutils literal"><span class="pre">$name</span></code> property, and be done with the Entity changes:</p>
|
||
<div class="highlight-ci"><div class="highlight"><pre><span></span><span class="o"><?</span><span class="nx">php</span> <span class="k">namespace</span> <span class="nx">App\Entities</span><span class="p">;</span>
|
||
|
||
<span class="k">use</span> <span class="nx">CodeIgniter\Entity</span><span class="p">;</span>
|
||
|
||
<span class="k">class</span> <span class="nc">User</span> <span class="k">extends</span> <span class="nx">Entity</span>
|
||
<span class="p">{</span>
|
||
<span class="k">protected</span> <span class="nv">$id</span><span class="p">;</span>
|
||
<span class="k">protected</span> <span class="nv">$name</span><span class="p">;</span> <span class="c1">// Represents a full name now</span>
|
||
<span class="k">protected</span> <span class="nv">$email</span><span class="p">;</span>
|
||
<span class="k">protected</span> <span class="nv">$password</span><span class="p">;</span>
|
||
<span class="k">protected</span> <span class="nv">$created_at</span><span class="p">;</span>
|
||
<span class="k">protected</span> <span class="nv">$updated_at</span><span class="p">;</span>
|
||
|
||
<span class="k">protected</span> <span class="nv">$_options</span> <span class="o">=</span> <span class="p">[</span>
|
||
<span class="s1">'datamap'</span> <span class="o">=></span> <span class="p">[</span>
|
||
<span class="s1">'full_name'</span> <span class="o">=></span> <span class="s1">'name'</span>
|
||
<span class="p">],</span>
|
||
<span class="s1">'dates'</span> <span class="o">=></span> <span class="p">[</span><span class="s1">'created_at'</span><span class="p">,</span> <span class="s1">'updated_at'</span><span class="p">,</span> <span class="s1">'deleted_at'</span><span class="p">],</span>
|
||
<span class="s1">'casts'</span> <span class="o">=></span> <span class="p">[]</span>
|
||
<span class="p">];</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>By adding our new database name to the <code class="docutils literal"><span class="pre">$datamap</span></code> array, we can tell the class what class property the database column
|
||
should be accessible through. The key of the array is the name of the column in the database, where the value in the array
|
||
is class property to map it to.</p>
|
||
<p>In this example, when the model sets the <code class="docutils literal"><span class="pre">full_name</span></code> field on the User class, it actually assigns that value to the
|
||
class’ <code class="docutils literal"><span class="pre">$name</span></code> property, so it can be set and retrieved through <code class="docutils literal"><span class="pre">$user->name</span></code>. The value will still be accessible
|
||
through the original <code class="docutils literal"><span class="pre">$user->full_name</span></code>, also, as this is needed for the model to get the data back out and save it
|
||
to the database. However, <code class="docutils literal"><span class="pre">unset</span></code> and <code class="docutils literal"><span class="pre">isset</span></code> only work on the mapped property, <code class="docutils literal"><span class="pre">$name</span></code>, not on the original name,
|
||
<code class="docutils literal"><span class="pre">full_name</span></code>.</p>
|
||
</div>
|
||
<div class="section" id="mutators">
|
||
<h2><a class="toc-backref" href="#id8">Mutators</a><a class="headerlink" href="#mutators" title="Permalink to this headline">¶</a></h2>
|
||
<div class="section" id="date-mutators">
|
||
<h3><a class="toc-backref" href="#id9">Date Mutators</a><a class="headerlink" href="#date-mutators" title="Permalink to this headline">¶</a></h3>
|
||
<p>By default, the Entity class will convert fields named <cite>created_at</cite>, <cite>updated_at</cite>, or <cite>deleted_at</cite> into
|
||
<a class="reference internal" href="../libraries/time.html"><span class="doc">Time</span></a> instances whenever they are set or retrieved. The Time class provides a large number
|
||
of helpful methods in an immutable, localized way.</p>
|
||
<p>You can define which properties are automatically converted by adding the name to the <strong>options[‘dates’]</strong> array:</p>
|
||
<div class="highlight-ci"><div class="highlight"><pre><span></span><span class="o"><?</span><span class="nx">php</span> <span class="k">namespace</span> <span class="nx">App\Entities</span><span class="p">;</span>
|
||
|
||
<span class="k">use</span> <span class="nx">CodeIgniter\Entity</span><span class="p">;</span>
|
||
|
||
<span class="k">class</span> <span class="nc">User</span> <span class="k">extends</span> <span class="nx">Entity</span>
|
||
<span class="p">{</span>
|
||
<span class="k">protected</span> <span class="nv">$id</span><span class="p">;</span>
|
||
<span class="k">protected</span> <span class="nv">$name</span><span class="p">;</span> <span class="c1">// Represents a full name now</span>
|
||
<span class="k">protected</span> <span class="nv">$email</span><span class="p">;</span>
|
||
<span class="k">protected</span> <span class="nv">$password</span><span class="p">;</span>
|
||
<span class="k">protected</span> <span class="nv">$created_at</span><span class="p">;</span>
|
||
<span class="k">protected</span> <span class="nv">$updated_at</span><span class="p">;</span>
|
||
|
||
<span class="k">protected</span> <span class="nv">$_options</span> <span class="o">=</span> <span class="p">[</span>
|
||
<span class="s1">'dates'</span> <span class="o">=></span> <span class="p">[</span><span class="s1">'created_at'</span><span class="p">,</span> <span class="s1">'updated_at'</span><span class="p">,</span> <span class="s1">'deleted_at'</span><span class="p">],</span>
|
||
<span class="s1">'casts'</span> <span class="o">=></span> <span class="p">[],</span>
|
||
<span class="s1">'datamap'</span> <span class="o">=></span> <span class="p">[]</span>
|
||
<span class="p">];</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Now, when any of those properties are set, they will be converted to a Time instance, using the application’s
|
||
current timezone, as set in <strong>app/Config/App.php</strong>:</p>
|
||
<div class="highlight-ci"><div class="highlight"><pre><span></span><span class="nv">$user</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">App\Entities\User</span><span class="p">();</span>
|
||
|
||
<span class="c1">// Converted to Time instance</span>
|
||
<span class="nv">$user</span><span class="o">-></span><span class="na">created_at</span> <span class="o">=</span> <span class="s1">'April 15, 2017 10:30:00'</span><span class="p">;</span>
|
||
|
||
<span class="c1">// Can now use any Time methods:</span>
|
||
<span class="k">echo</span> <span class="nv">$user</span><span class="o">-></span><span class="na">created_at</span><span class="o">-></span><span class="na">humanize</span><span class="p">();</span>
|
||
<span class="k">echo</span> <span class="nv">$user</span><span class="o">-></span><span class="na">created_at</span><span class="o">-></span><span class="na">setTimezone</span><span class="p">(</span><span class="s1">'Europe/London'</span><span class="p">)</span><span class="o">-></span><span class="na">toDateString</span><span class="p">();</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="property-casting">
|
||
<h3><a class="toc-backref" href="#id10">Property Casting</a><a class="headerlink" href="#property-casting" title="Permalink to this headline">¶</a></h3>
|
||
<p>You can specify that properties in your Entity should be converted to common data types with the <strong>casts</strong> entry in
|
||
the <strong>$_options</strong> property. The <strong>casts</strong> option should be an array where the key is the name of the class property,
|
||
and the value is the data type it should be cast to. Casting only affects when values are read. No conversions happen
|
||
that affect the permanent value in either the entity or the database. Properties can be cast to any of the following
|
||
data types: <strong>integer</strong>, <strong>float</strong>, <strong>double</strong>, <strong>string</strong>, <strong>boolean</strong>, <strong>object</strong>, <strong>array</strong>, <strong>datetime</strong>, and
|
||
<strong>timestamp</strong>. Add question mark at the beginning of type to mark property as nullable, i.e. <strong>?string</strong>, <strong>?integer</strong>.</p>
|
||
<p>For example, if you had a User entity with an <strong>is_banned</strong> property, you can cast it as a boolean:</p>
|
||
<div class="highlight-ci"><div class="highlight"><pre><span></span><span class="o"><?</span><span class="nx">php</span> <span class="k">namespace</span> <span class="nx">App\Entities</span><span class="p">;</span>
|
||
|
||
<span class="k">use</span> <span class="nx">CodeIgniter\Entity</span><span class="p">;</span>
|
||
|
||
<span class="k">class</span> <span class="nc">User</span> <span class="k">extends</span> <span class="nx">Entity</span>
|
||
<span class="p">{</span>
|
||
<span class="k">protected</span> <span class="nv">$is_banned</span><span class="p">;</span>
|
||
|
||
<span class="k">protected</span> <span class="nv">$_options</span> <span class="o">=</span> <span class="p">[</span>
|
||
<span class="s1">'casts'</span> <span class="o">=></span> <span class="p">[</span>
|
||
<span class="s1">'is_banned'</span> <span class="o">=></span> <span class="s1">'boolean'</span><span class="p">,</span>
|
||
<span class="s1">'is_banned_nullable'</span> <span class="o">=></span> <span class="s1">'?boolean'</span>
|
||
<span class="p">],</span>
|
||
<span class="s1">'dates'</span> <span class="o">=></span> <span class="p">[</span><span class="s1">'created_at'</span><span class="p">,</span> <span class="s1">'updated_at'</span><span class="p">,</span> <span class="s1">'deleted_at'</span><span class="p">],</span>
|
||
<span class="s1">'datamap'</span> <span class="o">=></span> <span class="p">[]</span>
|
||
<span class="p">];</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="array-json-casting">
|
||
<h3><a class="toc-backref" href="#id11">Array/Json Casting</a><a class="headerlink" href="#array-json-casting" title="Permalink to this headline">¶</a></h3>
|
||
<p>Array/Json casting is especially useful with fields that store serialized arrays or json in them. When cast as:</p>
|
||
<ul class="simple">
|
||
<li>an <strong>array</strong>, they will automatically be unserialized,</li>
|
||
<li>a <strong>json</strong>, they will automatically be set as an value of json_decode($value, false),</li>
|
||
<li>a <strong>json-array</strong>, they will automatically be set as an value of json_decode($value, true),</li>
|
||
</ul>
|
||
<p>when you read the property’s value.
|
||
Unlike the rest of the data types that you can cast properties into, the:</p>
|
||
<ul class="simple">
|
||
<li><strong>array</strong> cast type will serialize,</li>
|
||
<li><strong>json</strong> and <strong>json-array</strong> cast will use json_encode function on</li>
|
||
</ul>
|
||
<p>the value whenever the property is set:</p>
|
||
<div class="highlight-ci"><div class="highlight"><pre><span></span><span class="o"><?</span><span class="nx">php</span> <span class="k">namespace</span> <span class="nx">App\Entities</span><span class="p">;</span>
|
||
|
||
<span class="k">use</span> <span class="nx">CodeIgniter\Entity</span><span class="p">;</span>
|
||
|
||
<span class="k">class</span> <span class="nc">User</span> <span class="k">extends</span> <span class="nx">Entity</span>
|
||
<span class="p">{</span>
|
||
<span class="k">protected</span> <span class="nv">$options</span><span class="p">;</span>
|
||
|
||
<span class="k">protected</span> <span class="nv">$_options</span> <span class="o">=</span> <span class="p">[</span>
|
||
<span class="s1">'casts'</span> <span class="o">=></span> <span class="p">[</span>
|
||
<span class="s1">'options'</span> <span class="o">=></span> <span class="s1">'array'</span><span class="p">,</span>
|
||
<span class="s1">'options_object'</span> <span class="o">=></span> <span class="s1">'json'</span><span class="p">,</span>
|
||
<span class="s1">'options_array'</span> <span class="o">=></span> <span class="s1">'json-array'</span>
|
||
<span class="p">],</span>
|
||
<span class="s1">'dates'</span> <span class="o">=></span> <span class="p">[</span><span class="s1">'created_at'</span><span class="p">,</span> <span class="s1">'updated_at'</span><span class="p">,</span> <span class="s1">'deleted_at'</span><span class="p">],</span>
|
||
<span class="s1">'datamap'</span> <span class="o">=></span> <span class="p">[]</span>
|
||
<span class="p">];</span>
|
||
<span class="p">}</span>
|
||
|
||
<span class="nv">$user</span> <span class="o">=</span> <span class="nv">$userModel</span><span class="o">-></span><span class="na">find</span><span class="p">(</span><span class="mi">15</span><span class="p">);</span>
|
||
<span class="nv">$options</span> <span class="o">=</span> <span class="nv">$user</span><span class="o">-></span><span class="na">options</span><span class="p">;</span>
|
||
|
||
<span class="nv">$options</span><span class="p">[</span><span class="s1">'foo'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'bar'</span><span class="p">;</span>
|
||
|
||
<span class="nv">$user</span><span class="o">-></span><span class="na">options</span> <span class="o">=</span> <span class="nv">$options</span><span class="p">;</span>
|
||
<span class="nv">$userModel</span><span class="o">-></span><span class="na">save</span><span class="p">(</span><span class="nv">$user</span><span class="p">);</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
</div>
|
||
<div class="articleComments">
|
||
|
||
</div>
|
||
</div>
|
||
<footer>
|
||
|
||
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
|
||
|
||
<a href="../dbmgmt/index.html" class="btn btn-neutral float-right" title="Managing Databases" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right"></span></a>
|
||
|
||
|
||
<a href="model.html" class="btn btn-neutral" title="Using CodeIgniter’s Model" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> Previous</a>
|
||
|
||
</div>
|
||
|
||
|
||
<hr/>
|
||
|
||
<div role="contentinfo">
|
||
<p>
|
||
© Copyright 2014-2019 British Columbia Institute of Technology.
|
||
Last updated on Apr 10, 2019.
|
||
|
||
</p>
|
||
</div>
|
||
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||
|
||
</footer>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
</section>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript">
|
||
var DOCUMENTATION_OPTIONS = {
|
||
URL_ROOT:'../',
|
||
VERSION:'4.0.0-beta.2',
|
||
COLLAPSE_INDEX:false,
|
||
FILE_SUFFIX:'.html',
|
||
HAS_SOURCE: false,
|
||
SOURCELINK_SUFFIX: ''
|
||
};
|
||
</script>
|
||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript" src="../_static/js/theme.js"></script>
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript">
|
||
jQuery(function () {
|
||
SphinxRtdTheme.StickyNav.enable();
|
||
});
|
||
</script>
|
||
|
||
|
||
</body>
|
||
</html> |