Here's what I'm trying to do: I've got a db.php file that does all the db manipulation.
It has 2 static methods, connect and deconnect.
In my other file i simply use db::connect() and db::deconnect(). The mysql_close($con) in the deconnect method just doesn't know who $con is.
Since I don't want to instantiate my class static is the only way to go.
Declaring 'private $con' in class db doesn't seem to have an effect.
Any ideas?
class db {
public static function connect() {
$dbData = parse_ini_file($_SERVER['DOCUMENT_ROOT'].'/config.ini');
$con = mysql_connect($dbData['host'],$dbData['user'],$dbData['pass']);
$db = mysql_select_db($dbData['db']);
if ((!$con) || (!$db))
return 0;
else return 1;
}
public static function deconnect() {
mysql_close($con);
}
}
In deconnect, $con is out of scope.
You should make it a static member, like this:
class db {
static $con;
public static function connect() {
$dbData = parse_ini_file($_SERVER['DOCUMENT_ROOT'].'/config.ini');
self::$con = mysql_connect($dbData['host'],$dbData['user'],$dbData['pass']);
$db = mysql_select_db($dbData['db']);
if ((!self::$con) || (!$db))
return 0;
else return 1;
}
public static function deconnect() {
if( !isset( self::$con ) ) return;
mysql_close( self::$con );
}
}
The message makes sense as $con is out of scope in your deconnect() method (deconnect...?).
Use a static data member
class db {
static $con;
}
Access it through self::$con.
Well, it seems to me that $con is a local variable (local to the method connect). Thus, when you call mysql_close, most likely $con is undefined. Try declaring $con as a private variable in your class. Look here for more info on how to do that.
Related
I have an yii2 project with the advanced template and I want to implement notifications using a mosquitto broker.
I already have the publish part done and working, now I'd like to have some help on subscribing to a topic on my frontend app. I already tried, but the page seems to stop working when I subscribe to any topic.
Is there any easy way or tutorial that I can use? If any more information is needed, please ask.
P.S: My idea was: When I open any page on frontend, I check for messages, save them in a array, set them as view param and then render my page.
EDIT: So far i've tried the following
Class
<?php
namespace common\models;
use Yii;
class Notificacoes
{
private $listaNotificacoes;
public function __construct($id, $name)
{
$this->listaNotificacoes = array();
$server = "127.0.0.1";
$port = 1883;
$username = "";
$password = "";
$client_id = $id;
$mqtt = new \common\mosquitto\phpMQTT($server, $port, $client_id);
if(!$mqtt->connect(true, NULL, $username, $password)) {
exit(1);
}
$topics[$name] = array("qos" => 0, "function" => "procmsg");
$mqtt->subscribe($topics, 0);
while($mqtt->proc()){
}
$mqtt->close();
}
function procmsg($topic, $msg)
{
\array_push($this->listaNotificacoes, $msg);
}
public function getAll()
{
return $this->listaNotificacoes;
}
}
SiteController: I tried to get the messages on the beforeAction method
public function beforeAction($action)
{
if (!parent::beforeAction($action)) {
return false;
}
$notifications = array();
if (!Yii::$app->user->isGuest)
{
$notifs = new Notificacoes(Yii::$app->user->identity->getId(), Yii::$app->user->identity->username);
$notifications = $notifs->getAll();
}
$this->view->params['notifications'] = $notifications;
return true;
}
This model is unlikely to work because normally messages are only delivered by MQTT at the instant they are published.
So unless you are using retained messages or persistent subscriptions for a given client id to queue messages. This means your while loop will never have any messages to process
Is there any posibility in PhpStorm to map usage of dynamic generated fucntion between it declaration an usage?
Assume I have next code:
<?php
class TestExample {
public function __construct($component) {
$component_parts = $this->get_dynamic_component_part_list($component);
$this->load_component_parts($component, $component_parts);
}
private function get_dynamic_component_part_list($component){
//Complex logic to get attached parts by $component
$component_parts = array('part1', 'part2');
return $component_parts;
}
private function load_component_parts(&$component, $component_parts) {
foreach ($component_parts as $component_part) {
$component[$component_part] = $this->{'load_' . $component_part}($component['id']);
}
}
private function load_part1($id) {
//Loading and prepare condition from one source
$part1 = new Part1($id);
// Complex algorithm
return $part1;
}
private function load_part2($id) {
//Loading and prepare condition from another source
$part2 = new Part2($id);
// Complex algorithm
return $part2;
}
}
class Part1 {
}
class Part2 {
}
I want to see usage of load_part1 and load_part2.
Is there any way to do it by usage phpDoc or in some other way?
At this moment PhpStorm notice me that this function doesn't have usage but realy it used in load_component_parts method.
You can use the phpDoc annotation #see.
For example:
$className = 'SomeClass';
$method = 'methodToCall';
$anArgument = 'bar';
/** #see SomeClass::someMethod() */
$foo = call_user_func([$className, $method], $anArgument);
This annotation will create at least a reference to this code, so that you know to come back here when you review SomeClass::someMethod() before throwing the "unused" method away.
While running PHPUnit tests, a lot of connections are created but not closed.
I can see this in
mysql> show processlist;
In my database class I create a db connection by implementing PHPUnit_Extensions_Database_TestCase#getConnection().
I make sure that in the teardown the connection gets closed. See snippet:
<?php
abstract class My_Tests_DatabaseTestCase extends \PHPUnit_Extensions_Database_TestCase
{
static private $pdo = null;
private $conn = null;
/**
* #throws RuntimeException
* #return PHPUnit_Extensions_Database_DB_IDatabaseConnection
*/
final public function getConnection()
{
$iniFilePath = __DIR__ . '/../../../db-config.ini';
$iniFile = parse_ini_file($iniFilePath, true);
$dsn = "mysql:dbname=".$iniFile['phpunit']['dbname'].";host=".$iniFile['phpunit']['host'];
if ( $this->conn === null ) {
if ( self::$pdo == null ) {
self::$pdo = new \PDO($dsn, $iniFile['phpunit']['user'], $iniFile['phpunit']['password']);
}
$this->conn = $this->createDefaultDBConnection(self::$pdo, $iniFile['phpunit']['dbname']);
}
return $this->conn;
}
protected function getSetUpOperation()
{
return new \PHPUnit_Extensions_Database_Operation_Composite(array(
new \TestsExtensions\TruncateDatabaseOperation(),
\PHPUnit_Extensions_Database_Operation_Factory::INSERT()
));
}
protected function getTearDownOperation() {
return \PHPUnit_Extensions_Database_Operation_Factory::TRUNCATE();
}
protected function setUp()
{
parent::setUp();
$em = \ORM\Provider::getInstance()->getEntityManager(\ORM\Provider::DEFAULT_ID);
$em->clear();
}
protected function tearDown()
{
parent::tearDown();
$em = \ORM\Provider::getInstance()->getEntityManager(\ORM\Provider::DEFAULT_ID);
$em->getConnection()->close();
if ($this->conn) {
$this->conn->close();
}
}
}
Debugging showed that the connections were closed, but the processlist showed them with status "sleep".
The amount of connections rises until I get the "too many connections" error.
I do not want to increase the number of connections. I want to close the connection.
What can I modify to make this happen?
Snippet from PDO Connection management:
Upon successful connection to the database, an instance of the PDO
class is returned to your script. The connection remains active for
the lifetime of that PDO object. To close the connection, you need to
destroy the object by ensuring that all remaining references to it are
deleted--you do this by assigning NULL to the variable that holds the
object. If you don't do this explicitly, PHP will automatically close
the connection when your script ends.
Don't store the PDO or set it to null in the teardown:
Remove static private $pdo = null;
or
protected function tearDown()
{
parent::tearDown();
$em = \ORM\Provider::getInstance()->getEntityManager(\ORM\Provider::DEFAULT_ID);
$em->getConnection()->close();
if ($this->conn) {
$this->conn->close();
}
self::$pdo = null;
}
I don't think you need to store the PDO if you are going to pass it into the PHPUnit DB connection
I have these classes below for my online store.
This super class holds all common methods used by the child classes.
class grandpa
{
public function test1($string)
{
return $string;
}
}
So do the PDO connection,
class database_pdo extends grandpa
{
protected $connection = null;
protected $dsn,$username,$password;
public function __construct($dsn,$username,$password)
{
$this->dsn = $dsn;
$this->username = $username;
$this->password = $password;
$this->get_connection();
}
public function get_connection()
{
try
{
$this->connection = new PDO($this->dsn, $this->username, $this->password, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e)
{
$this->get_error($e);
}
}
public function __sleep()
{
return array('dsn', 'username', 'password');
}
public function __wakeup()
{
$this->get_connection();
}
public function get_error($e)
{
$this->connection = null;
die($e->getMessage());
}
public function __destruct()
{
$this->connection = null;
}
}
I have this class extend from pdo for other common methods that require pdo connection,
class papa extends database_pdo
{
protected $connection = null;
public function __construct($connection)
{
$this->connection = $connection;
}
public function test2($string)
{
return $string;
}
}
The child classes,
class kido_1 extends papa
{
public function __construct($connection)
{
parent::__construct($connection);
}
public function test3($string)
{
return $string;
}
}
How it use the classes above,
# Host used to access DB.
define('DB_HOST', 'localhost');
# Username used to access DB.
define('DB_USER', 'xxx');
# Password for the username.
define('DB_PASS', 'xxx');
# Name of your databse.
define('DB_NAME', 'xxx');
# Data source name.
define('DSN', 'mysql:host='.DB_HOST.';dbname='.DB_NAME);
$connection = new database_pdo(DSN,DB_USER,DB_PASS);
$kido = new kido($connection);
$_SESSION['cart'] = serialize($kido);
$kido = unserialize($_SESSION['cart']);
print_r($kido->test3('hello'));
I get this error,
invalid data source name
It is caused by unserialize() that I need it for my cart data...
How can I fix this? Or a better way of rewrite these classes?
Your papa::connection is a PDO object. Therefore, when you are trying to serialize $kido, you are trying to serialize a resource, which is not possible.
Try adding a $this->connection = null; in your database_pdo::__sleep() method.
a solution I think...
class papa extends grandpa
{
protected $connection = null;
public function __construct($connection)
{
$this->connection = $connection;
}
public function test2($string)
{
return $string;
}
}
Trying to use __construct inside a controller to assign some variable but it keeps throwing errors. Hoping that someone can lead me in the right direction.
class Controller_Mobile extends Controller {
public function __construct()
{
parent::__construct();
$iphoneDetect = strpos($_SERVER['HTTP_USER_AGENT'],"iPhone");
$touchDetect = strpos($_SERVER['HTTP_USER_AGENT'],"iPod");
$blackberry = strpos ($_SERVER['HTTP_USER_AGENT'], 'blackberry');
$android = strpos ($_SERVER['HTTP_USER_AGENT'], 'android');
$iphoneDetect = true;
if ($iphoneDetect == true || $touchDetect == true)
{
$directory = "mobile/iphone";
}
else if($android == true)
{
$directory = "mobile/android";
}
}
public function action_index()
{
$this->request->response = 'I am mobile';
}
I actually just found the answer to the question and just thought i would pass it along. In Kohana 3 you use the before() and after() functions.
You have to use both request and response in construct.
public function __construct(Request $request, Response $response)
{
parent::__construct($request,$response);
// your code
}
If you want to use __construct() method, dont forget about Request variable:
public function __construct(Kohana_Request $request)
{
parent::__construct($request);
// your code
}
Thats why you are getting errors with your code.