PHP - Dependency Injection Via Setter Method
Could use some help with dependency injection, as I can't seem to find the answer anywhere. Ok, take a quick PHP class:
<?php namespace myapp; use myapp\template; use myapp\order; class user { private $template; public function __construct(template $template) { $this->template = $template; } public function add_order(order $order) { // do something with $order here } }
I'm using the php-di package from http://php-di.org/ right now, but open to changing. My question is, how do I call that "add_order()" method, and have $order injected into it? Constructor injection is easy, and just use:
$container = new Di\Container(); $container->make(myapp\user);
How do I do that, but calling the add_order() method instead? I want something like:
$container = new Di\Container(); $container->make(myapp\user::add_order);
Any help?
Thanks, Matt
Similar TutorialsI'm trying to use dependency injection to pass a database connection to an object but I'm not sure why it's not working. I have my "dbClass" below that connects to a MySQL database. Code: [Select] class dbClass { public $db; function __construct() { $this->db = mysql_connect("localhost","username","password") or die ('Could not connect: ' . mysql_error()); return $this->db; } } Then I have my "baseClass". This is the class that I want to feed to connection too. Code: [Select] class baseClass { public $mysql_conn; function __construct($db) { $this->mysql_conn = $db; $rs = mysql_select_db("webdev_db", $this->mysql_conn) or die ('Could not connect: ' . mysql_error()); } } And this is my index.php file. The error I'm getting is "supplied argument is not a valid MySQL-Link resource". However I tripled checked and my db connection details are definately correct. Code: [Select] $db = new dbClass(); $baseclass = new baseClass($db); Thanks for any help. I need to create an entity which models the connection between a PHP server and another device so that a web app can change the entity's properties which in turn will update the server DB as well as the other device. A little background information for context is as follows: When a socket clients connects to the PHP server, it will register by providing its GUID, and in turn the server will query its DB to identify the specific client. The client has various other properties associated with the socket connection such as reconnect_timeout, response_timeout, etc, and the associated values will also be stored in the server's DB. While all socket clients use the same approach to communicate to the PHP server, several "flavors" of socket clients exists which use a specific protocol (Modbus/RTU, Modbus/IP, ControlNet, BACnet/IP, BACnet/MSTP, KNX, DALI) to communicate to downstream devices. Based on the used protocol, there will be different properties as well as different methods (i.e. some protocols allow one to query the device to retrieve a list of available data). To create the entity using inheritance, I would likely do so whe class ModbusRtuSocketClient extends ModbusSocketClient (which extends SocketClient) class ModbusIpSocketClient extends ModbusSocketClient (which extends SocketClient) class ControlNetSocketClient extends SocketClient etc.. But instead of doing so by using inheritance, I am thinking that I should do so through injection. For instance, I create an object called SocketClient which just deals with that scope of work and is protocol agnostic. I also create a second object which deals with a given protocol such as ModbusRtuProtocol extends ModbusProtocol extends Protocol. I then do one of the following: $entity = new SocketClient(new ModbusRtuProtocol()); //or $entity = new ModbusRtuProtocol(new SocketClient()); //and do $entity->setSomeSocketClientProperty(123); $entity->getProperty()->setSomeSpecificProtocolProperty(321); $entity->updateEndDevice(); $entityManager->persist($entity); $entityManager->flush(); //or do $values=$entity->queryDevice();
PS. If you think I shouldn't be doing so through injection but through inheritance, please advise. This topic has been moved to Application Design. http://www.phpfreaks.com/forums/index.php?topic=346818.0 I'm looking for some clarification here from different viewpoints to understand real world applications. In a previous thread, I suggested to someone that they read up on singleton methods to restrict class duplication (oops!), I was quickly (and rightfully) shot down. I did this after having read through blog posts that also suggested singleton design to stop multiple MySQL connections. At the time I didn't consider that could be useful to some people.. fair enough. Thankfully I don't use singleton methods within my own code, but I do use static methods for most things. Reading through numerous blog posts, tutorials, etc.., it seems like static methods can also be considered anti-design and is something to avoid. So now it seems I'm at a point where I need to rewrite my existing framework & CMS, probably using dependency injection within my classes. I understand how this works, and why it makes sense. What I'm struggling with is understanding how to use dependency injection within a (personal) CMS application. For example - I have a config.ini file I have a class that reads the .ini file, stores the variables, and provides me methods to access them I have a content class that selects the relevant page/component from the DB (db & config dependency), then displays it via my template engine. Within the included view files I call component classes (articles, contact, etc..), each of these require a connection to the DB, which has a config dependency. Here's some code to explain it better - index.php <?php $settings = '/config/config.ini'; $config = new Config($settings); $db = new Database($config); $content = new Content( $db ); // Config may also be passed for content config - keeping it simple for example print $content->loadPage($_GET['page']); // This would now include the code below ?>Let's say that this then loads the article index (through $content->loadPage()). The view would look something like this - article_index.php <?php // Duplicated code $settings = '/config/config.ini'; $config = new Config($settings); $db = new Database($config); // Article code $articles = new Articles_Model($db); return $articles->getArticles(0,15); ?>Now my problem is that I'm duplicating the config and db class calls for no reason. Is the sollution to store these within a registry class? But then I'm creating globals, which again seems anti-design. Or is the problem how I load the active page? Any insights would be much appreciated. Hi all. I'm just getting my feet wet with OOPHP. My question is "why have a setter method when you can just use the __construct method to set everything?" and "would you need a separate setter method for each attribute of an object?"(i.e. set_first, set_last, set_gender, etc.) The code... <?php class person{ var $first; var $last; var $gender; function __construct($first,$last,$gender){ $this->first=$first; $this->last=$last; $this->gender=$gender; } function set_first($new_name){ $this->first=$new_name; } function get_person(){ return $this->first . $this->last . $this->gender; } } ?> Was just wondering why some people choose NOT to make use of static functions when initializing objects via Factory Classes/Containers. What are the benefits of initializing the Factory class when for all intensive purposes, it's only used to initialize new classes, etc? Does this have any impact on Dependency Injection? I'm assuming that it doesn't since that would defeat the purpose. --------- Also, I've noticed that there seems to be an intense stigma within the development community in regard to singletons. Are singletons necessarily a bad thing? What about database objects? One argument I've heard is that this can often impact the flexibility of your application in the event that a new instance of said class needs to be initialized(a second completely separate connection). However, I was thinking that you could simply store these objects within a static member variable in the factory class; leaving the Database Class' __construct public in the event that you need to create that second/third/fourth connection. Wouldn't this resolve the issue? I just updated a site as follows: cd /var/www/concrete5 composer update Among other changes, the following were made (more on this later): - Updating concrete5/core (8.5.2 => 8.5.4): Downloading (100%) - Updating doctrine/collections (1.6.4 => 1.6.5): Downloading (100%) - Updating doctrine/lexer (1.2.0 => 1.2.1): Downloading (100%) - Updating doctrine/inflector (1.3.1 => 1.4.3): Downloading (100%) - Updating doctrine/cache (1.10.0 => 1.10.1): Downloading (100%) - Updating doctrine/annotations (1.10.2 => 1.10.3): Downloading (100%) - Updating doctrine/common (2.12.0 => 2.13.3): Downloading (100%) - Updating doctrine/instantiator (1.3.0 => 1.3.1): Downloading (100%) - Updating doctrine/orm (v2.7.2 => v2.7.3): Downloading (100%)
errno: 150 "Foreign key constraint is incorrectly formed I expected I should have first used concrete5's update script, but too late for that. So, then I changed composer.json require concrete5/core from ^8.5 to 8.5.2 hoping to return to the previous state. Concreete5 was downgraded as desired, but now I get the following error: Class 'Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain' not found On another concrete5 site which still works, I have the following two files, however, on the broken one I only have the second: vendor/doctrine/persistence/lib/Doctrine/Common/Persistence/Mapping/Driver/MappingDriverChain.php:13: class MappingDriverChain extends \Doctrine\Persistence\Mapping\Driver\MappingDriverChain vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/MappingDriverChain.php:17:class MappingDriverChain implements MappingDriverSo, now I will attempt to downgrade doctrine from 2.7.3 to 2.7.2. The base composer.json file has no reference to Doctrine, but there are two other related composer files: vendor/concrete5/doctrine-xml/composer.json { "name": "concrete5/doctrine-xml", "description": "Define database structure via XML using Doctrine data types", "keywords": [ "doctrine", "xml", "structure", "database", "schema" ], "homepage": "https://github.com/concrete5/doctrine-xml", "license": "MIT", "autoload": { "psr-4": { "DoctrineXml\\": "src/" } }, "require": { "php": ">=5.3" }, "require-dev": { "doctrine/dbal": "2.5.*" } } vendor/concrete5/dependency-patches/composer.json { "type":"library", "license":"MIT", "name":"concrete5/dependency-patches", "description":"Patches required for concrete5 dependencies", "homepage":"https://github.com/concrete5/dependency-patches", "authors":[ { "name":"Michele Locati", "email":"michele@locati.it", "role":"author", "homepage":"https://mlocati.github.io" } ], "require":{ "mlocati/composer-patcher": "^1.0.0" }, "extra":{ "patches": { "doctrine/annotations:1.2.7": { "Fix access array offset on value of type null": "doctrine/annotations/access-array-offset-on-null.patch" }, "doctrine/orm:2.5.14": { "Fix UnitOfWork::createEntity()": "doctrine/orm/UnitOfWork-createEntity-continue.patch" }, "zendframework/zend-stdlib:2.7.7": { "Fix ArrayObject::unserialize()": "zendframework/zend-stdlib/ArrayObject-unserialize-continue.patch" }, "sunra/php-simple-html-dom-parser:1.5.2": { "Fix minus in regular expressions": "sunra/php-simple-html-dom-parser/minus-in-regular-expressions.patch" }, "phpunit/phpunit:4.8.36": { "Avoid each() in Getopt": "phpunit/phpunit/Getopt-each.patch" }, "tedivm/jshrink:1.1.0": { "Fix continue switch in Minifier": "tedivm/jshrink/fix-minifier-loop.patch", "Update to upstream version 1.3.2": "tedivm/jshrink/update-upstream-1.3.2.patch" }, "zendframework/zend-code:2.6.3": { "Fix continue switch in FileGenerator and MethodReflection": "zendframework/zend-code/switch-continue.patch" }, "zendframework/zend-http:2.6.0": { "Remove support for the X-Original-Url and X-Rewrite-Url headers": "zendframework/zend-http/no-x-original-url-x-rewrite.patch" }, "zendframework/zend-mail:2.7.3": { "Fix idn_to_ascii deprecation warning": "zendframework/zend-mail/fix-idn_to_ascii-deprecation-warning.patch" }, "zendframework/zend-validator:2.8.2": { "Fix idn_to_ascii/idn_to_utf8 deprecation warning": "zendframework/zend-validator/fix-idn_to_-deprecation-warning.patch" } } } } Neither seem to be applicable, but the doctrine version has to be specified somewhere. How does composer determine which version and how can I downgrade the dependency package? Thanks
PS. As a hack solution, I replaced the entire vendor/doctrine directory from one from another site, and have things working. Still, want to know how to do this right. Edited June 12, 2020 by NotionCommotionI am on a shared hosting server running CentOS. I have copied a PHP extension (imagick.so) that was built on similar server to my shared hosting server. I have resolved most of the dependencies by placing the missing files in ~/lib but I have one that I can't figure out how to cope with. I am getting the following error:
My script has 3 classes (that are relevant to this discussion): DB, User and Validate. They are all in independent files and loaded automatically, when required, by an autoloader.
The error messages I am getting a Any pointers as to what I am doing wrong, or what I should be doing, would be most welcome. I am having a wamp issue so I can't try these out right now. According to the book I'm learning php with, I can easily avoid injection attacks this way:
$a= stripslashes($a);
$a= mysql_real_escape_string($a);
What concerns me is the repetition of the variable, $a. Does it matter? Intuitively, it should.
$a changes. By the time $a hits mysql_real_escape_string it is slash-free. So it is a totally different "value" but still contained in the original variable which may have had slashes...just has me concerned a bit.
I know PDOs are the best way. I'm not there yet, unfortunately.
Edited by baltar, 23 May 2014 - 10:36 AM. I'm confused, can this result in css/sql injection? Code: [Select] if(isset($_GET['action'])){ if($_GET['action'] == 'details'){ $cupID = $_GET['cupID']; $ergebnis = safe_query("SELECT gameaccID, name, start, ende, typ, game, `desc`, status, checkin, maxclan, gewinn1, gewinn2, gewinn3 FROM ".PREFIX."cups WHERE ID = '".$cupID."'"); $ds=mysql_fetch_array($ergebnis); ... Some german fellow was explaining, translate to English briefly: "$ CupID is not escaped. NEN here I could just "; DROP TABLE` cups `Paste and your table is no longer available eez. Or I could inject javascript, your current session read out, accept it and act as an admin ... " I am trying to understand what he means by this... is this query vulnerable to an injection and why/how? Will this prevent a SQL injection? I am guessing the answer is no because it is too simple. // retrieve form data ========================================== $ama = $_POST['ama']; // Check for alphanumeric characters ===================================== $string = "$ama"; $new_string = preg_replace("/[^a-zA-Z0-9\s]/", "", $string); // echo $new_string; // Send query =========================================================== $query = "SELECT * FROM members WHERE ama='$new_string'"; if (!mysql_query($query)){ die('Error :' .mysql_error()); } Hi, I'm sure many of you heard of "pastebin", if not the short of it, is that you can submit your code (+100 languages), and you can display it to your friends via a link with syntax highlighting available. So, One way to store the code is surely in txt files, but I would really prefer to have it stored in a mysql database. My only concern is people trying to run a sql injection, so how do i get around all this? I don't want the user's content to be changed, but I don't want SQL injections either.. is this even possible at all? Any tips appreciated, also if you could think of another alternative than txt files and mysql. I want to know which part of my script has the hole..as i can find lots of php script and even folder can be injected into my public_html how they do that, and which part need to be checked? is that the upload part <enctype> or what?? thanks in advance i just want to ask this simple question let say i have this basic query $place=$_GET['place']; mysql_query("SELECT * FROM table WHERE place='$place'"); this is a nice target for sql injection.. but what if i replace the whole special characters that could be added $replacethis=array("-","`"); $withthis=array("",""); $place=str_replace($replacethis,$withthis,$_GET['place']); mysql_query("SELECT * FROM table WHERE place='$place'"); Are they still able to do the basic sql injection by trying to get the error by adding special character although i didn't use mysql_real_escape_string() ?? then what if i protect the file by changing the setting of the permission to either 644 or 755? thanks in advance Based on the comments on my previous question, took some tutorials on how to avoid injections on query. Does the code below prevents against it in any way.? Secondly, can you recommend a good article that writes well in how to secure input data by users. Please be kind with your comments.😉😉. Thankks in advance.
The code works fine. <?php include 'db.php'; error_reporting(E_ALL | E_WARNING | E_NOTICE); ini_set('display_errors', TRUE); if(isset($_POST['submit'])) { $username = $_POST['username']; $password = ($_POST['password']); $sql = "SELECT * FROM customer WHERE username = ?"; $stmt = $connection->prepare($sql); $stmt->bind_param('s', $username); $stmt->execute(); $result = $stmt->get_result(); $count = $result->num_rows; if($count == 1) { while ($row = $result->fetch_assoc()) { if ($row['status'] == 'blocked') { echo'your account is suspended' session_destroy(); exit(); } else if($row['status'] == 'active') { if($username !== $row['username']) { echo '<script>swal.fire("ERROR!!", " Username is not correct. Check Again", "error");</script>'; } if($password !== $row['password']) { echo'<script>swal.fire("ERROR!!!", "Your Password is Incorrect. Check Again.", "error");</script>'; } if($username == $row['username'] && $password == $row['password']) { header('Location:cpanel/'); else { } }//if count }//while loop }//submit ?>
Hello, I have a video game site - mostly vBulletin which is fine but there are a few extra bits to the site that I have done myself. I'm pretty new to PHP so my code isn't great. Anyway, I wanted to test my code for SQL Injection but I looked on Google and most of the tools seemed to come from hacker sites etc which I'm not downloading. I eventually found an addon for Firefox called SQL Inject Me and ran that. It said everything was alright but when I checked my MySQL tables they were full of junk code it had inserted. One of my pages doesn't even have any visible fields. It's just a page with a voting submit button and some hidden fields so how does it inject the code into the tables? The insert page code is: Code: [Select] $db = mysql_connect("localhost", "username", "password"); mysql_select_db("thedatabase",$db); $ipaddress = mysql_real_escape_string($_POST['ipaddress']); $theid = mysql_real_escape_string($_POST['theid']); $gamert = mysql_real_escape_string($_POST['gamert']); $serveron = mysql_real_escape_string($_POST['serveron']); $check= mysql_query("select * from voting2 where ipaddress='$ipaddress'"); $ipname = mysql_fetch_assoc($check); if($ipname['ipaddress'] == $ipaddress) { echo 'It appears you have already voted. Click <a href="vote.php">here</a> to return to the votes.'; } else { mysql_query ("INSERT INTO voting2 (theid,ipaddress,gamert,serveron2) VALUES ('$theid','$ipaddress','$gamert','$serveron')"); echo 'Your vote has been added. Click <a href="vote.php">here</a> to view the updated totals.'; } How can I make it safer against SQL injection? Thanks Hello People, Been reading up on these and trying to understand them more. Say I have a file called page.php?id=12345 and when users hit the page I run this code in the background: $id = $_GET['id']; $query = "UPDATE tbl SET live = '1' WHERE id = '".$id."'"; That page is not open to any attack right? Even though i'm using $_GET. Am I right in thinking that attacks only happen on online forms. So for example there is no way an attacker could somehow output all the data in my table tbl Thank yo (I'm putting this in PHP since it's not a question specific to MySQL or other DB stuff.)
I have a page that uses the GET id to find a product. GET variables are sanitized, and the SQL string is escaped even though it's expecting a number only. So the code seems safe to me. I'm getting some error_log results that appear to be hack attempts:
SELECT |