bjyoungblood / bjyprofiler Goto Github PK
View Code? Open in Web Editor NEWZendDeveloperTools-compatible Zend\Db query profile
License: BSD 3-Clause "New" or "Revised" License
ZendDeveloperTools-compatible Zend\Db query profile
License: BSD 3-Clause "New" or "Revised" License
I spent 2 hours trying to figure out how to configure my db connection for UTF8 encoding. I figured it out, but I suggest adding a 'driver_options' element to the configuration array in the Readme.md:
$dbParams = array(
'database' => 'changeme',
'username' => 'changeme',
'password' => 'changeme',
'hostname' => 'localhost',
// buffer_results - only for mysqli buffered queries, skip for others
'options' => array('buffer_results' => true),
'driver_options' => array() //!!!!!!!!!!!!!!!!! here and....
);
return array(
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter' => function ($sm) use ($dbParams) {
$adapter = new BjyProfiler\Db\Adapter\ProfilingAdapter(array(
'driver' => 'pdo',
'dsn' => 'mysql:dbname='.$dbParams['database'].';host='.$dbParams['hostname'],
'database' => $dbParams['database'],
'username' => $dbParams['username'],
'password' => $dbParams['password'],
'hostname' => $dbParams['hostname'],
'driver_options' => $dbParams['driver_options'], // HERE !!!!!!!!!!!!!!!!
));
//....
The option by the way is:
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8'
)
Thanks.
When I install BjyProfiler with the new ZendSkeletonApplication and Zend\Mvc 3 all ZF components are installed. Even Barcode and Captcha. I have no idea why this happens but it should be solved.
Zend Framework 2 now ships with an Oracle adapter.
With Adapter::QUERY_MODE_PREPARE and some code it works.
$statement = $this->db->query($sql, Adapter::QUERY_MODE_PREPARE);
$result = $statement->execute();
$results = clone $this->db->getQueryResultSetPrototype();
$results->initialize($result);
Composer depency to ZF2 should be at least 2.1 instead of 2.0
if i want to create a custom adapter into Module.php i get an error: cannot create service with the same name.
It's because BjyProfiler contain a custom config who create a factory by default.
I suggest to clear the config file and just make its content optionnal.
There is an example who can generate the error:
i'm building a multi website application. Each website is a module and need to get it's own adapter, so i did that:
class Module
{
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$this->bootstrapDb($e);
}
public function bootstrapDb(MvcEvent $e)
{
$e->getApplication()->getEventManager()->getSharedManager()
->attach('Zend\Mvc\Controller\AbstractActionController', 'dispatch', function ($e) {
// Comment this line to get the error
$e->getApplication()->getServiceManager()->setAllowOverride(true);
/** @var AbstractActionController $controller */
$controller = $e->getTarget();
$controllerClass = get_class($controller);
$moduleNamespace = substr($controllerClass, 0, strpos($controllerClass, '\\'));
$dbConfig = $e->getApplication()->getServiceManager()->get('config')['db'];
// Global Application config
$config = array_merge(
array_intersect_key(
$dbConfig,
array_flip(array('username', 'password', 'driver', 'dsn', 'options'))
),
$dbConfig[strtolower($moduleNamespace)]
);
$controller->getServiceLocator()->setFactory(
'Zend\Db\Adapter\Adapter',
function ($sm) use ($config) {
$adapter = new \BjyProfiler\Db\Adapter\ProfilingAdapter($config);
$adapter->setProfiler(new \BjyProfiler\Db\Profiler\Profiler);
if (isset($config['options']) && is_array($config['options'])) {
$options = $config['options'];
} else {
$options = array();
}
$adapter->injectProfilingStatementPrototype($options);
return $adapter;
}
);
}, 100);
}
}
So i have to set AllowOverride to true in serviceManager to get it working
Hi I have in my file local.php multiple Db and in my global.php file my
'service_manager' => array (
'abstract_factories' => array (
'Zend \ Db \ Adapter \ AdapterAbstractServiceFactory'
)
)
as I set it up??
When I'am using the MasterSlaveFeature (ref) it breaks the profiler with giving 0 executed queries.
Is this a bug or is there a workaround for this?
I can confirm that it does profile PDO prepared statements. It does not however profile raw SQL, which is a problem because I need to write a performance test that asserts my code does some operation in only 1 query.
Here's a test case that exposes the flaw in your code.
function testBjy()
{
// insert some data & select it back, so we can see queries actually ran. THis is 2 queries
$this->db->query("INSERT INTO `product` (sku) value ('test')", \Zend\Db\Adapter\Adapter::QUERY_MODE_EXECUTE);
$result = $this->db->query("SELECT * FROM `product`", \Zend\Db\Adapter\Adapter::QUERY_MODE_EXECUTE);
print_r($result->toArray());
// running 2 more queries!
$this->db->query("SELECT count(*) FROM `product`", \Zend\Db\Adapter\Adapter::QUERY_MODE_EXECUTE);
$this->db->query("SELECT * FROM `product`", \Zend\Db\Adapter\Adapter::QUERY_MODE_EXECUTE);
// lets ask it how many queries its seen, should be 4 :)
$profiler = $this->db->getProfiler();
$queryProfiles = $profiler->getQueryProfiles();
$afterCount = count($queryProfiles);
// it says it has seen no queries :/
var_dump($afterCount); // 0
// some sanity checking.
var_dump(get_class($profiler));
var_dump(get_class($this->db));
}
$ phpunit --filter=testBjy
.Array
(
[0] => Array
(
[id] => 135
[sku] => test
)
)
# here its saying theres 0 queries
int(0)
# this proves its indeed your code running.
string(32) "BjyProfiler\Db\Profiler\Profiler"
string(39) "BjyProfiler\Db\Adapter\ProfilingAdapter"
I have the following version of your code loaded: 1ca3161
Here's my profiler object, the bitwise filter is set to all types clearly:
class BjyProfiler\Db\Profiler\Profiler#396 (3) {
protected $profiles =>
array(0) {
}
protected $enabled =>
bool(true)
protected $filterTypes =>
int(127)
}
I threw a debug statement into Query::start() -
echo 'got here';exit;
It does not hit that line when running my above test.
How can I use BjyProfiler with SQLite? I have some problem with create config files. Help me, please...
Hi,
Please can you draft a new release with very last version of the master branch
Thank you
\BjyProfiler\Db\Adapter\ProfilingAdapter is no longer compatible with Zend Framework 2.3
This error happened after update from 2.2.x to 2.3
Strict standards: Declaration of BjyProfiler\Db\Adapter\ProfilingAdapter::query() should be compatible with Zend\Db\Adapter\Adapter::query($sql, $parametersOrQueryMode = 'prepare', Zend\Db\ResultSet\ResultSetInterface $resultPrototype = NULL) in \vendor\bjyoungblood\bjy-profiler\src\BjyProfiler\Db\Adapter\ProfilingAdapter.php on line 11
Hi there,
Following files are missing :
Maybe more...
See https://github.com/bjyoungblood/BjyProfiler/blob/master/Module.php
Please, help
Hi, I wonder if this is generated by your module or not...
I have a model class whose "store" method is called :
public function store(Event $e) {
$data = array(
/** some data /
) ;
/ .. . */
$this->tableGateway->insert($data);
}
The problem is under this level. I don't know if it's your module which generates this or ZF2... Could you have a look at it please.
I get the following error :
Zend\Db\Adapter\Exception\InvalidQueryException
vendor/zendframework/zendframework/library/Zend/Db/Adapter/Driver/Pdo/Statement.php:220
with message "Statement could not be executed"
and previous exception message was :
SQLSTATE[HY000]: General error: 907 OCIStmtExecute: ORA-00907: missing right parenthesis
(/builddir/build/BUILD/php-5.4.6/ext/pdo_oci/oci_statement.c:148)
with stack trace :
#0 /home/jeff/projects/winyumweb/zf2/vendor/zendframework/zendframework/library/Zend/Db/Adapter/Driver/Pdo/Statement.php(218): PDOStatement->execute()
#1 /home/jeff/projects/winyumweb/zf2/vendor/bjyoungblood/bjy-profiler/src/BjyProfiler/Db/Adapter/Driver/Pdo/ProfilingStatement.php(31): Zend\Db\Adapter\Driver\Pdo\Statement->execute(NULL)
#2 /home/jeff/projects/winyumweb/zf2/vendor/zendframework/zendframework/library/Zend/Db/TableGateway/AbstractTableGateway.php(295): BjyProfiler\Db\Adapter\Driver\Pdo\ProfilingStatement->execute()
#3 /home/jeff/projects/winyumweb/zf2/vendor/zendframework/zendframework/library/Zend/Db/TableGateway/AbstractTableGateway.php(262): Zend\Db\TableGateway\AbstractTableGateway->executeInsert(Object(Zend\Db\Sql\Insert))
#4 /home/jeff/projects/winyumweb/zf2/module/Application/src/Application/Model/EventTable.php(73): Zend\Db\TableGateway\AbstractTableGateway->insert(Array)
#5 /home/jeff/projects/winyumweb/zf2/module/Application/src/Application/Controller/WinyumController.php(150): Application\Model\EventTable->store(Object(Application\Entity\Event))
#6 /home/jeff/projects/winyumweb/zf2/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractActionController.php(87): Application\Controller\WinyumController->lockAction()
#7 [internal function]: Zend\Mvc\Controller\AbstractActionController->onDispatch(Object(Zend\Mvc\MvcEvent))
#8 /home/jeff/projects/winyumweb/zf2/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(464): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#9 /home/jeff/projects/winyumweb/zf2/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(208): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#10 /home/jeff/projects/winyumweb/zf2/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractController.php(108): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#11 /home/jeff/projects/winyumweb/zf2/vendor/zendframework/zendframework/library/Zend/Mvc/DispatchListener.php(113): Zend\Mvc\Controller\AbstractController->dispatch(Object(Zend\Http\PhpEnvironment\Request), Object(Zend\Http\PhpEnvironment\Response))
#12 [internal function]: Zend\Mvc\DispatchListener->onDispatch(Object(Zend\Mvc\MvcEvent))
#13 /home/jeff/projects/winyumweb/zf2/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(464): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#14 /home/jeff/projects/winyumweb/zf2/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(208): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#15 /home/jeff/projects/winyumweb/zf2/vendor/zendframework/zendframework/library/Zend/Mvc/Application.php(297): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#16 /home/jeff/projects/winyumweb/zf2/public/index.php(15): Zend\Mvc\Application->run()
#17 {main}
composer.json classmap no existe se necesita para recrear la autollamada del modulo
Fatal error: Uncaught exception 'Exception' with message 'Serialization of 'Closure' is not allowed' in /var/www/project/vendor/zendframework/zend-developer-tools/src/ZendDeveloperTools/Profiler.php on line 217
Not certain whose bug it is. Especially considering to this $this->report->addCollector(unserialize(serialize($collector)));
in ZendDeveloperTools\Profiler line 217
Probably need to modify the composer.json requirement for dev-master now
"zendframework/zendframework": "dev-master"
should be updated to be (I think)
"zendframework/zendframework": ">=2.0.0"
Currently if you include it by packagist, it forces you to make zendframework dev-master, which is now tracking as 2.0.1
It would be nice to view the queries inside the toolbar's container similar to the Doctrine profiler.
Denis Ryabov posted a solution for this inside the toolbars template:
http://stackoverflow.com/questions/13275569/how-to-view-db-queries-generated-by-tablegateway-in-zend-framework-2
Is it possible?
If i put HTML code in any module.config.php like example, then the Toolbar crashed:
'view_helper_config' => array(
'flashmessenger' => array(
'message_open_format' => '<div%s><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button><ul><li>',
'message_close_string' => '</li></ul></div>',
'message_separator_string' => '</li><li>'
)
)
Update readme to reflect this component works with the built-in Profiler now.
First of all, thank you for your module. It's fair and useful. I have 2 questions about it :
Why is your level of requirement set to 5.3.6 ? (I'm experiencing issues because the up2date version on my CentOS 5.8 server is 5.3.3 so I can't use your module)
Your module is the only one I've found which makes it possible to work with a Oracle Database. Is your adapter capable of working with Oracle Lobs ?
Thanks in advance.
Fatal error: Declaration of BjyProfiler\Db\Adapter\ProfilingAdapter::setProfiler() must be compatible with that of Zend\Db\Adapter\Profiler\ProfilerAwareInterface::setProfiler() in E:\web\whatsapp\vendor\BjyProfiler\src\BjyProfiler\Db\Adapter\ProfilingAdapter.php on line 9
A bit like #33.
<?php
require "./vendor/autoload.php";
use Zend\Log;
use BjyProfiler\Db\Adapter\ProfilingAdapter;
use BjyProfiler\Db\Profiler;
$dbParams = array(
'driver' => "Pdo_Sqlite",
'database' => ":memory:",
);
$adapter = new ProfilingAdapter($dbParams);
$logger = new Log\Logger();
$writer = new Log\Writer\Stream('php://output');
$logger->addWriter($writer, Log\Logger::DEBUG);
$adapter->setProfiler(new Profiler\LoggingProfiler($logger));
$adapter->injectProfilingStatementPrototype(array());
echo "prepare/execute\n";
$adapter->query("SELECT 1")->execute();
echo "execute mode\n";
$adapter->query("SELECT 2", $adapter::QUERY_MODE_EXECUTE);
Output is:
prepare/execute
2013-11-25T15:00:48+00:00 DEBUG (7): Query started {"sql":"SELECT 1","parameters":"[]"}
2013-11-25T15:00:48+00:00 DEBUG (7): Query finished {"elapsed":0.022835969924927}
execute mode
Looks like LoggingProfiler needs to wrap startQuery and endQuery in addition to profilerStart and profilerFinish.
Hey,
You might want to include abstract service factory. Sorry I'm too lazy to do a patch so I'll just paste the code here:
getConfig($services); if (empty($config)) { return false; } return ( isset($config[$requestedName]) && is_array($config[$requestedName]) && !empty($config[$requestedName]) ); } /** * Create a DB adapter * * @param ServiceLocatorInterface $services * @param string $name * @param string $requestedName * @return Adapter */ public function createServiceWithName(ServiceLocatorInterface $services, $name, $requestedName) { $config = $this->getConfig($services); $dbParams = $config[$requestedName]; $adapter = new ProfilingAdapter($dbParams); $adapter->setProfiler(new Profiler); if (isset($dbParams['options']) && is_array($dbParams['options'])) { $options = $dbParams['options']; } else { $options = array(); } $adapter->injectProfilingStatementPrototype($options); return $adapter; } /** * Get db configuration, if any * * @param ServiceLocatorInterface $services * @return array */ protected function getConfig(ServiceLocatorInterface $services) { if ($this->config !== null) { return $this->config; } if (!$services->has('Config')) { $this->config = array(); return $this->config; } $config = $services->get('Config'); if (!isset($config['db']) || !is_array($config['db']) ) { $this->config = array(); return $this->config; } $config = $config['db']; if (!isset($config['adapters']) || !is_array($config['adapters']) ) { $this->config = array(); return $this->config; } $this->config = $config['adapters']; return $this->config; } ``` }Source code is missing a license. Also, for due dillegence anything ported from ZF1 should include the following in order to comply with their licensing terms (I believe you can add yourself as a new copyright line):
Copyright (c) 2005-2010, Zend Technologies USA, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of Zend Technologies USA, Inc. nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Overall, I'd suggest you adopt this same license for this project. It's the exact same license zf2 uses, except the date is updated.
Hi,
i've tried to install the profiler via composer with the following content:
"require": {
"php": ">=5.3.3",
"zendframework/zendframework": "dev-master",
"zendframework/zend-developer-tools": "dev-master",
"zf-commons/zfc-user": "dev-master",
"zendframework/zftool": "dev-master",
"bjyoungblood/bjy-profiler" : "dev-master"
}
I've also tried it with zendframework stable 2.3.0 and bjy-profiler version 1.1.0 - didn't work though. After adding the module to my application.config.php, the following error appears:
Zend\ModuleManager\Exception\RuntimeException: Module (bjyoungblood/bjy-profiler) could not be initialized.
I read the existing issues to that error in the issues list, but couldn't figure out why it is not working for my setup.
thx in advance for some hints
magnus
Hi!
Is it possible to configure multiple databases for databases profiling?
If not possible for now, then it might be a good feature to develop.
Thank you!
Is there also a version that isn't using the zend_db but rather uses doctrine?
I found this package while searching for a way to set up FirePHP with my ZF2/Doctrine2 project. Any tips or examples of profiling ZF2/Doctrine2 with FirePHP?
When using with latest ZF3
return [
'service_manager' => [
'factories' => [
Adapter::class => ProfilingAdapterFactory::class,
],
],
];
ProfilingAdapterFactory throws error: Fatal error: Class BjyProfiler\Db\Adapter\ProfilingAdapterFactory contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Zend\ServiceManager\Factory\FactoryInterface::__invoke)
I am trying to add BjyProfiler in Zend Frameword 3. It is displaying the following error.
`File:
/var/www/html/projects/zend/writeup.local/vendor/zendframework/zend-servicemanager/src/ServiceManager.php:765
Message:
Service with name "Zend\Db\Adapter\AdapterInterface" could not be created. Reason: The supplied or instantiated driver object does not implement Zend\Db\Adapter\Driver\DriverInterface`
Could you please tag a release so composer can use its internal cache?
Steps to reproduce:
Result exception: Zend\ModuleManager\Exception\RuntimeException: Module (BjyProfiler) could not be initialized.
Can't understand the reason and wasn't able tot google anything!
You might want to consider adding a $dbParams['driver_options'] key to the /config/autoload file, then pass it to the db adapter upon creation. I would use it to set the default fetch style, for example:
'driver_options' => array(PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC),
Nice work, by the way.
Notice: Use of undefined constant DEBUG_BACKTRACE_IGNORE_ARGS - assumed 'DEBUG_BACKTRACE_IGNORE_ARGS' in \vendor\bjyoungblood\BjyProfiler\src\BjyProfiler\Db\Adapter\Driver\Pdo\ProfilingStatement.php on line 24
Zend\Db\Adapter\Profiler\ProfilerInterface::profilerStart($target)
must take either a string or a Zend\Db\Adapter\StatementContainerInterface
as the $target
parameter. The current BjyProfiler\Db\Profiler\Profiler
implementation fails when given a string.
The simplest solution would be to fix the implementation in BjyProfiler\Db\Profiler\Profiler
to check the type of the $target
and process accordingly. However, I wonder if it wouldn't be better for BjyProfiler\Db\Profiler\Profiler
to extend Zend\Db\Adapter\Profiler\Profiler
to take advantage of its profilerStart($target)
which already implements that logic. Let me know, I'll be happy to submit a pull request either way.
It was very interesting for me why there are so many queries on my pages so I implemented simple queries list browser using code from http://stackoverflow.com/questions/13275569/how-to-view-db-queries-generated-by-tablegateway-in-zend-framework-2 and I found that it shows all queries twice. First one has source (stack trace) and the second one always has execution time = 0 and empty stack trace.
Here is picture of my current queries list panel (it's ugly but better than nothing) with doubled queries http://i.imgur.com/AQ8C5Oq.png
Here is gist https://gist.github.com/vgarvardt/5133500 with patched db panel (and styles) so you could try it live (and maybe use as a base for much-wanted and long-waited #23 implementation)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.