The document discusses dependency injection in PHP. It begins with a real-world web application example to demonstrate dependency injection, showing how the User class depends on a SessionStorage class. It then explains how using constructor injection for the dependency rather than hardcoding it makes the code more customizable, configurable, and testable. Dependency injection decouples classes and makes them more reusable and replaceable. The document advocates using a dependency injection container to manage object instantiation and dependencies.
Can't Miss Features of PHP 5.3 and 5.4Jeff Carouth
If you're like me you remember the days of PHP3 and PHP4; you remember when PHP5 was released, and how it was touted to change to your life. It's still changing and there are some features of PHP 5.3 and new ones coming with PHP 5.4 that will improve your code readability and reusability. Let's look at some touted features such as closures, namespaces, and traits, as well as some features being discussed for future releases.
This talk is an overview of the history of the PHP language and major framework projects that have emerged in the last 5 years. It examines what we've learned in the development of these frameworks, how that education has been brought to bear in Lithium. Most of this talk ended up being me demoing and answering questions, so there's not a lot of content in the slides, sorry.
Caching and Scaling WordPress using Fragment CachingErick Hitter
Using what I’ve learned working on the WordPress.com VIP platform, this presentation discusses caching techniques applicable to WordPress installations of almost any size.
Presented February 18, 2012 at WordCamp Miami.
Original HTML5 slides are available at http://www.ethitter.com/2012/02/caching-and-scaling-wcmia/.
Can't Miss Features of PHP 5.3 and 5.4Jeff Carouth
If you're like me you remember the days of PHP3 and PHP4; you remember when PHP5 was released, and how it was touted to change to your life. It's still changing and there are some features of PHP 5.3 and new ones coming with PHP 5.4 that will improve your code readability and reusability. Let's look at some touted features such as closures, namespaces, and traits, as well as some features being discussed for future releases.
This talk is an overview of the history of the PHP language and major framework projects that have emerged in the last 5 years. It examines what we've learned in the development of these frameworks, how that education has been brought to bear in Lithium. Most of this talk ended up being me demoing and answering questions, so there's not a lot of content in the slides, sorry.
Caching and Scaling WordPress using Fragment CachingErick Hitter
Using what I’ve learned working on the WordPress.com VIP platform, this presentation discusses caching techniques applicable to WordPress installations of almost any size.
Presented February 18, 2012 at WordCamp Miami.
Original HTML5 slides are available at http://www.ethitter.com/2012/02/caching-and-scaling-wcmia/.
Come to this talk prepared to learn about the Doctrine PHP open source project. The Doctrine project has been around for over a decade and has evolved from database abstraction software that dates back to the PEAR days. The packages provided by the Doctrine project have been downloaded almost 500 million times from packagist. In this talk we will take you through how to get started with Doctrine and how to take advantage of some of the more advanced features.
Generating a custom Ruby SDK for your web service or Rails API using Smithyg2nightmarescribd
Have you ever wanted a Ruby client API to communicate with your web service? Smithy is a protocol-agnostic language for defining services and SDKs. Smithy Ruby is an implementation of Smithy that generates a Ruby SDK using a Smithy model. In this talk, we will explore Smithy and Smithy Ruby to learn how to generate custom feature-rich SDKs that can communicate with any web service, such as a Rails JSON API.
Transcript: Selling digital books in 2024: Insights from industry leaders - T...BookNet Canada
The publishing industry has been selling digital audiobooks and ebooks for over a decade and has found its groove. What’s changed? What has stayed the same? Where do we go from here? Join a group of leading sales peers from across the industry for a conversation about the lessons learned since the popularization of digital books, best practices, digital book supply chain management, and more.
Link to video recording: https://bnctechforum.ca/sessions/selling-digital-books-in-2024-insights-from-industry-leaders/
Presented by BookNet Canada on May 28, 2024, with support from the Department of Canadian Heritage.
Securing your Kubernetes cluster_ a step-by-step guide to success !KatiaHIMEUR1
Today, after several years of existence, an extremely active community and an ultra-dynamic ecosystem, Kubernetes has established itself as the de facto standard in container orchestration. Thanks to a wide range of managed services, it has never been so easy to set up a ready-to-use Kubernetes cluster.
However, this ease of use means that the subject of security in Kubernetes is often left for later, or even neglected. This exposes companies to significant risks.
In this talk, I'll show you step-by-step how to secure your Kubernetes cluster for greater peace of mind and reliability.
Connector Corner: Automate dynamic content and events by pushing a buttonDianaGray10
Here is something new! In our next Connector Corner webinar, we will demonstrate how you can use a single workflow to:
Create a campaign using Mailchimp with merge tags/fields
Send an interactive Slack channel message (using buttons)
Have the message received by managers and peers along with a test email for review
But there’s more:
In a second workflow supporting the same use case, you’ll see:
Your campaign sent to target colleagues for approval
If the “Approve” button is clicked, a Jira/Zendesk ticket is created for the marketing design team
But—if the “Reject” button is pushed, colleagues will be alerted via Slack message
Join us to learn more about this new, human-in-the-loop capability, brought to you by Integration Service connectors.
And...
Speakers:
Akshay Agnihotri, Product Manager
Charlie Greenberg, Host
State of ICS and IoT Cyber Threat Landscape Report 2024 previewPrayukth K V
The IoT and OT threat landscape report has been prepared by the Threat Research Team at Sectrio using data from Sectrio, cyber threat intelligence farming facilities spread across over 85 cities around the world. In addition, Sectrio also runs AI-based advanced threat and payload engagement facilities that serve as sinks to attract and engage sophisticated threat actors, and newer malware including new variants and latent threats that are at an earlier stage of development.
The latest edition of the OT/ICS and IoT security Threat Landscape Report 2024 also covers:
State of global ICS asset and network exposure
Sectoral targets and attacks as well as the cost of ransom
Global APT activity, AI usage, actor and tactic profiles, and implications
Rise in volumes of AI-powered cyberattacks
Major cyber events in 2024
Malware and malicious payload trends
Cyberattack types and targets
Vulnerability exploit attempts on CVEs
Attacks on counties – USA
Expansion of bot farms – how, where, and why
In-depth analysis of the cyber threat landscape across North America, South America, Europe, APAC, and the Middle East
Why are attacks on smart factories rising?
Cyber risk predictions
Axis of attacks – Europe
Systemic attacks in the Middle East
Download the full report from here:
https://sectrio.com/resources/ot-threat-landscape-reports/sectrio-releases-ot-ics-and-iot-security-threat-landscape-report-2024/
Neuro-symbolic is not enough, we need neuro-*semantic*Frank van Harmelen
Neuro-symbolic (NeSy) AI is on the rise. However, simply machine learning on just any symbolic structure is not sufficient to really harvest the gains of NeSy. These will only be gained when the symbolic structures have an actual semantics. I give an operational definition of semantics as “predictable inference”.
All of this illustrated with link prediction over knowledge graphs, but the argument is general.
DevOps and Testing slides at DASA ConnectKari Kakkonen
My and Rik Marselis slides at 30.5.2024 DASA Connect conference. We discuss about what is testing, then what is agile testing and finally what is Testing in DevOps. Finally we had lovely workshop with the participants trying to find out different ways to think about quality and testing in different parts of the DevOps infinity loop.
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Albert Hoitingh
In this session I delve into the encryption technology used in Microsoft 365 and Microsoft Purview. Including the concepts of Customer Key and Double Key Encryption.
Key Trends Shaping the Future of Infrastructure.pdfCheryl Hung
Keynote at DIGIT West Expo, Glasgow on 29 May 2024.
Cheryl Hung, ochery.com
Sr Director, Infrastructure Ecosystem, Arm.
The key trends across hardware, cloud and open-source; exploring how these areas are likely to mature and develop over the short and long-term, and then considering how organisations can position themselves to adapt and thrive.
3. In most web applications, you need to manage the user preferences
–The user language
–Whether the user is authenticated or not
–The user credentials
–…
4. This can be done with a User object
–setLanguage(), getLanguage()
–setAuthenticated(), isAuthenticated()
–addCredential(), hasCredential()
–...
5. The User information
need to be persisted
between HTTP requests
We use the PHP session for the Storage
6. class SessionStorage
{
function __construct($cookieName = 'PHP_SESS_ID')
{
session_name($cookieName);
session_start();
}
function set($key, $value)
{
$_SESSION[$key] = $value;
}
// ...
}
7. class User
{
protected $storage;
function __construct()
Very hard to
{ customize
$this->storage = new SessionStorage();
}
function setLanguage($language)
{
$this->storage->set('language', $language);
}
// ...
} Very easy to
use
$user = new User();
8. class User
{
protected $storage; Very easy to
customize
function __construct($storage)
{
$this->storage = $storage;
}
}
$storage = new SessionStorage();
$user = new User($storage);
Slightly more
difficult to use
12. class User
{
protected $storage;
H ardcode it in the
function __construct() User class
{
$this->storage = new SessionStorage('SESSION_ID');
}
function setLanguage($language)
{
$this->storage->set('language', $language);
}
// ...
}
$user = new User();
13. class User
{
protected $storage;
function __construct()
{
$this->storage = new SessionStorage(STORAGE_SESSION_NAME);
}
}
Add a global
configuration?
define('STORAGE_SESSION_NAME', 'SESSION_ID');
$user = new User();
14. class User
{
protected $storage;
function __construct($sessionName)
{
$this->storage = new SessionStorage($sessionName);
}
}
$user = new User('SESSION_ID');
Configure via
User?
15. class User
{
protected $storage;
function __construct($storageOptions)
{
$this->storage = new
SessionStorage($storageOptions['session_name']);
}
}
$user = new User(
array('session_name' => 'SESSION_ID')
);
Configure with an
array?
16. I want to change the session storage implementation
Filesystem
MySQL
Memcached
…
17. class User
{
protected $storage;
function __construct()
Use a global
{ registry object?
$this->storage = Registry::get('session_storage');
}
}
$storage = new SessionStorage();
Registry::set('session_storage', $storage);
$user = new User();
19. Instead of harcoding
the Storage dependency
inside the User class constructor
Inject the Storage dependency
in the User object
20. class User
{
protected $storage;
function __construct($storage)
{
$this->storage = $storage;
}
}
$storage = new SessionStorage('SESSION_ID');
$user = new User($storage);
23. class User
{
protected $storage;
function __construct($storage)
{
$this->storage = $storage;
} Use a different
} Storage engine
$storage = new MySQLSessionStorage('SESSION_ID');
$user = new User($storage);
25. class User
{
protected $storage;
function __construct($storage)
{
$this->storage = $storage;
} Configuration
} is natural
$storage = new MySQLSessionStorage('SESSION_ID');
$user = new User($storage);
27. class User
{
protected $storage; Add an interface
function __construct(SessionStorageInterface $storage)
{
$this->storage = $storage;
}
}
interface SessionStorageInterface
{
function get($key);
function set($key, $value);
}
29. class User
{
protected $storage;
function __construct(SessionStorageInterface $storage)
{
$this->storage = $storage;
}
}
Mock the Session
class SessionStorageForTests implements SessionStorageInterface
{
protected $data = array();
static function set($key, $value)
{
self::$data[$key] = $value;
}
}
30. Use different Storage strategies
Configuration becomes natural
Wrap third-party classes (Interface / Adapter)
Mock the Storage object (for testing)
Easy without changing the User class
31. « Dependency Injection is where
components are given their dependencies
through their constructors, methods, or
directly into fields. »
http://www.picocontainer.org/injection.html
32. $storage = new SessionStorage();
// constructor injection
$user = new User($storage);
// setter injection
$user = new User();
$user->setStorage($storage);
// property injection
$user = new User();
$user->storage = $storage;
34. $request = new Request();
$response = new Response();
$storage = new FileSessionStorage('SESSION_ID');
$user = new User($storage);
$cache = new FileCache(
array('dir' => __DIR__.'/cache')
);
$routing = new Routing($cache);
35. class Application
{
function __construct()
{
$this->request = new WebRequest();
$this->response = new WebResponse();
$storage = new FileSessionStorage('SESSION_ID');
$this->user = new User($storage);
$cache = new FileCache(
array('dir' => dirname(__FILE__).'/cache')
);
$this->routing = new Routing($cache);
}
}
$application = new Application();
37. class Application
{
function __construct()
{
$this->request = new WebRequest();
$this->response = new WebResponse();
$storage = new FileSessionStorage('SESSION_ID');
$this->user = new User($storage);
$cache = new FileCache(
array('dir' => dirname(__FILE__).'/cache')
);
$this->routing = new Routing($cache);
}
}
$application = new Application();
38. We need a Container
Describes objects
and their dependencies
Instantiates and configures
objects on-demand
39. A container
SHOULD be able to manage
ANY PHP object (POPO)
The objects MUST not know
that they are managed
by a container
40. • Parameters
–The SessionStorageInterface implementation we want to use (the class name)
–The session name
• Objects
–SessionStorage
–User
• Dependencies
–User depends on a SessionStorageInterface implementation
43. class Container
{
protected $parameters = array();
public function setParameter($key, $value)
{
$this->parameters[$key] = $value;
}
public function getParameter($key)
{
return $this->parameters[$key];
}
}
44. Decoupling
$container = new Container(); Customization
$container->setParameter('session_name', 'SESSION_ID');
$container->setParameter('storage_class', 'SessionStorage');
$class = $container->getParameter('storage_class');
$sessionStorage = new $class($container-
>getParameter('session_name'));
$user = new User($sessionStorage);
Objects creation
45. Using PHP
magic methods
class Container
{
protected $parameters = array();
public function __set($key, $value)
{
$this->parameters[$key] = $value;
}
public function __get($key)
{
return $this->parameters[$key];
}
}
46. Interface
is cleaner
$container = new Container();
$container->session_name = 'SESSION_ID';
$container->storage_class = 'SessionStorage';
$sessionStorage = new $container->storage_class($container-
>session_name);
$user = new User($sessionStorage);
55. class Container
{
protected $parameters = array();
protected $objects = array();
public function __set($key, $value)
{
$this->parameters[$key] = $value;
}
public function __get($key) Store a lambda
{
return $this->parameters[$key]; able to create the
} object on-demand
public function setService($key, Closure $service)
{
$this->objects[$key] = $service; the closure to create
Ask
} t and pass the
the objec
public function getService($key) current Container
{
return $this->objects[$key]($this);
}
}
56. Description
$container = new Container();
$container->session_name = 'SESSION_ID';
$container->storage_class = 'SessionStorage';
$container->setService('user', function ($c) {
return new User($c->getService('storage'));
});
$container->setService('storage', function ($c) {
return new $c->storage_class($c->session_name);
});
Creating the User
$user = $container->getService('user'); is now as easy as before
57. Order does not
$container = new Container(); matter
$container->setService('storage', function ($c) {
return new $c->storage_class($c->session_name);
});
$container->setService('user', function ($c) {
return new User($c->getService('storage'));
});
$container->session_name = 'SESSION_ID';
$container->storage_class = 'SessionStorage';
58. class Container Simplify the code
{
protected $values = array();
function __set($id, $value)
{
$this->values[$id] = $value;
}
function __get($id)
{
if (is_callable($this->values[$id])) {
return $this->values[$id]($this);
} else {
return $this->values[$id];
}
}
}
59. Unified interface
$container = new Container();
$container->session_name = 'SESSION_ID';
$container->storage_class = 'SessionStorage';
$container->user = function ($c) {
return new User($c->storage);
};
$container->storage = function ($c) {
return new $c->storage_class($c->session_name);
};
$user = $container->user;
66. A closure is a lambda
that remembers the context
of its creation…
67. class Article
{
public function __construct($title)
{
$this->title = $title;
}
public function getTitle()
{
return $this->title;
}
}
$articles = array(
new Article('Title 1'),
new Article('Title 2'),
);
73. function asShared(Closure $lambda)
{
return function ($container) use ($lambda)
{
static $object;
if (is_null($object)) {
$object = $lambda($container);
}
return $object;
};
}
74. class Container
{
protected $values = array();
function __set($id, $value)
{
$this->values[$id] = $value;
}
function __get($id) Error management
{
if (!isset($this->values[$id])) {
throw new InvalidArgumentException(sprintf('Value
"%s" is not defined.', $id));
}
if (is_callable($this->values[$id])) {
return $this->values[$id]($this);
} else {
return $this->values[$id];
}
}
}
75. class Container
{
protected $values = array();
function __set($id, $value)
{
$this->values[$id] = $value;
}
function __get($id)
{
if (!isset($this->values[$id])) {
throw new InvalidArgumentException(sprintf('Value "%s" is not defined.', $id));
}
if (is_callable($this->values[$id])) {
return $this->values[$id]($this);
} else {
return $this->values[$id];
}
}
function asShared($callable)
{
return function ($c) use ($callable) {
static $object;
if (is_null($object)) { 40 LO C for a fully-
}
$object = $callable($c);
feature d container
return $object;
};
}
}
76. $container = new Container();
$container->session_name = 'SESSION_ID';
$container->storage_class = 'SessionStorage';
$container->user = $container->asShared(function ($c) {
return new User($c->storage);
});
$container->storage = $container->asShared(function ($c) {
return new $c->storage_class($c->session_name);
});
96. namespace SymfonyComponentDependencyInjection;
interface ContainerInterface
{
function set($id, $service, $scope = self::SCOPE_CONTAINER);
function get($id, $invalidBehavior =
self::EXCEPTION_ON_INVALID_REFERENCE);
function has($id);
function getParameter($name);
function hasParameter($name);
function setParameter($name, $value);
function enterScope($name);
function leaveScope($name);
function addScope(ScopeInterface $scope);
function hasScope($name);
function isScopeActive($name);
}