Check if assets are installed in symfony2 - php

I am trying to run a unit test that checks if the assets are properly installed.
I simply make a request to an existing file and check if there is no errors:
$client = static::createClient();
$client->request('GET', '/bundles/mybundle/css/bg.css');
$this->assertFalse($client->getResponse()->isNotFound(), "Assets seem to not be installed");
Unfortunately, after checking with the Response instance, it always tries to reach some kind of controller with a route:
No route found for "GET /bundles/mybundle/css/bg.css"
Is there a way to make a pure request here without going through the routing system?

You'd need to use an actual HTTP client (the client implementation you are using for functional testing doesn't actually make HTTP requests) to make that request, but you seem to be approaching this the wrong way. Installing assets should be part of your post deployment scripts -- thus the test would always (or sometimes depending on the configuration of your development box, but the point is that it's a deployment/staging detail) fail anyway. Just do a simple test in your deployment process in any language you want to make sure that the assets installed correctly.
Simplified example
<?php
system('git clone myrepo');
echo 'Pulled codebase';
system('composer install'); // install dependencies
echo 'Dependencies installed';
system('php app/console assets:install web --symlink'); // install assets
echo 'Assets installed -- testing for presence';
if( !file_exists('blah.gif') ) {
echo 'assets not installed! error!';
}

The test client doesn't actually hit your web server, it simulates a request directly through your application.
Therefore it could never be used to check if an asset exists within your file structure. It could be used for dynamically loaded assets, but that's not the case here nor is it usually a case.
As #Lusitanian suggested, you can use standard file functions PHP has to offer to check if it exists.
If you need help locating the path of these assets, check out the Kernel::locateResource() method:
$this->container->get('kernel')->locateResource('#AcmeDemoBundle/Resources/public/css/main.css');
This will throw an exception if the resource was not found.

Related

Couchbase PHP Connect Hello World! on Mac

I installed the Couchbase Server and its PHP SDK through brew install libcouchbase on Mac. The server admin console is running/working fine on http://127.0.0.1:8091/. I added a hello.php file with the below code in /Library/WebServer/Documents/hello.php.
<?php
$cb = #new Couchbase("http://127.0.0.1:8091/",'username','password');
if($cb->getResultCode() != COUCHBASE_SUCCESS){
throw Exception('Cannot connect to couchbase!');
} else {
echo "Hello World!";
}
When I go to http://127.0.0.1:8091/hello.php, I get an error saying Not found.. What is the problem?
When I go to http://127.0.0.1:8091/hello.php, I get the below error
Not found.. What is the problem?
You are going to the wrong port. Port 8091 is the Couchbase Server Console interface. It looks like you are trying to deploy your hello.php script using the Apache server shipped with OS X which uses the default http port (80). The script is also located in the wrong folder. I believe /Library/WebServer/Documents/ is for static content only.
Given the problem you have ran into it make me suspect that you are trying to learn too many new things at once. You should try running the script outside of a Apache first and get it working there.
php hello.php
It is also worth pointing out that you are using the older 1.X version of the Couchbase PHP SDK, you will want to use the new 2.X version.
I assume you've anonymized the code above, but be sure in place of where you have 'username' you have the bucket name and similarly for the bucket password or empty string if no password. Also, check the docs as the connect string you're using is not necessarily the preferred..
Note for debugging these kinds of things you can set LCB_LOGLEVEL to a higher level as mentioned in the documentation. The way you set an envvar varies based on how you're deploying PHP, but you can easily just test it at the command line.

Using PHP APC cache in CLI mode using dumpfiles

I've recently started using APC cache on our servers. One of the most important parts of our product is a CLI (Cron/scheduled) process, whose performance is critical. Typically the batchjob consists of running some 16-32 processes in parallel for about an hour (they "restart" every few minutes).
By default, using APC cache in CLI is a waste of time due to the opcode cache not being retained between individual calls. But APC also contains apc_bin_dumpfile() and apc_load_dumpfile() functions.
I was thinking these two function might be used to make APC efficient in CLI mode by having it all compiled sometime outside the batchjob, stored in a single dumpfile and having the individual processes load the dumpfile.
Does anybody have any experience with such a scenario or can you give good reasons why it will or will not work? If any significant gains could reasonably be had, either in memory use or performance? What pitfalls are lurking in the shadows?
Disclaimer: As awesome as APC is when it works in CLI, and it is awesome, it can equally be as frustrating. Use with a healthy load of patience, be thorough, step away from the problem if you're spinning, keep in mind you are working with cache that is why it seems like its doing nothing, it is actually doing nothing. Delete dump file, start with just the basics, if that doesn't work forget it try a new machine, new OS, if it is working make a copy, piece by piece expand functionality - there are loads of things that won't work, if it is working commit or make a copy, add another piece and test again, for sanity-check recheck the copies that were working before, cliches or not; if at first you don't succeed try try again, you can't keep doing the same thing expecting new results.
Ready? This is what you've been waiting for:
Enable apc for cli
apc.enable-cli=1
it is not ideal to create, populate and destroy the APC cache on every CLI request
- previous answer by unknown poster since removed.
You're absolutely right that sucks, lets fix it shall we?
If you try and use APC under CLI and it is not enabled you will get warnings.
something like:
PHP Warning: apc_bin_loadfile(): APC is not enabled,
apc_bin_loadfile not available.
PHP Warning: apc_bin_dumpfile(): APC is not enabled,
apc_bin_dumpfile not available.
Warning: I suggest you don't enable cli in php.ini, it is not worth the frustration, you are going to forget you did it and have numerous other headaches with other scripts, trust me its not worth it, use a launcher script instead. (see below)
apc_loadfile and apc_dumpfile in cli
As per the comment by mightye php we need to disable apc.stat or you will get a warnings
something like:
PHP Warning: apc_bin_dumpfile(): Excluding some files from apc_bin_dump[file].
Cached files must be included using full path with apc.stat=0.
launcher script - php-apc.sh
We will use this script to launch our apc enabled scripts (ex. ./php-apc.sh apc-cli.php) instead of changing the properties in php.ini directly.
#/bin/sh
php -d apc.enable_cli=1 -d apc.stat=0 $1
Ready for the basic functionality? Sure you are =)
basic APC persisted - apc-cli.php
<?php
/** check if dump file exists, you don't want to use file_exists */
if (false !== $dump_file = stream_resolve_include_path('apc.dump'))
/** so where were we lets have a look see shall we */
if (false !== apc_bin_loadfile($dump_file))
/** fetch what was stored last run just for fun */
if (false !== $value = apc_fetch('my.awesome.apc.store'))
echo "$value from apc\n";
/** store what gets fetched the next run just for fun */
apc_store('my.awesome.apc.store', 'awesome in cli');
/** what a shlep lets not do that all over again shall we */
apc_bin_dumpfile(array(),null,'apc.dump');
Notice: Why not use file_exists? Because file_exists == stat you see and we want to reap the reward that is apc.stat=0 so; work within the include path; use absolute and not relative paths - as returned by stream_resolve_include_path(); avoid include_once, require_once use the non *_once counterparts; check your stat usage, when not using APC(Muchos important senor), with the help of a StreamWrapper echo for calls to method url_stat; Oops: Fatal scope over-run error! aborting notice thread. see url_stat
message: Error caused by StreamWrapper outside the scope of this discussion.
The smoke test
Using the launcher execute the basic script
./php-apc.sh apc-cli.php
A whole bunch of nothing happened that's what we want right, why else do you want to use cache? If it did output anything then it didn't work, sorry.
There should be a dump file called apc.dump see if you can find it? If you can't find it then it didn't work, sorry.
Good we have the dump file there were no errors lets run it again.
./php-apc.sh apc-cli.php
What you want to see:
awesome in cli from apc
Success! =)
There are few in PHP as satisfying as a working APC implementation.
nJoy!
I would definitely not use it in the CLI as when you restart it, it's almost as if it was never running in the first place!
The better way of using APC is to have it running on the webserver itself all the time, this way with it being active it will actually do what it's supposed to do!
I tryed with curl and APC.it works
use these commands in CLI
curl --data "param1=value2" http://testsite.com/test.php
so it will post data to test.php and you writes the code in it.

can you use curl to post to a local file?

I tried using curl to post to a local file and it fails. Can it be done? my two management systems are on the same server and it seems unnecessary to have it traverse the entire internet system just to go to a file on the same hard drive.
Using localhost didn't do the trick.
I also tried to $_SERVER[DOCUMENT_ROOT].'/dir/to/file.php' using post data. It's for an API that is encrypted, so I'm not sure exactly how it works. It's for a billing system I have and I just realized that it sends data back (API).
It's simply post data and an XML response. I could write an html form tag and input fields and get the same result, but there isn't really anything else to know.
The main question is: Does curl have the ability to post to a local file or not?
it is post data. it's for an API that is encrypted so i'm not sure exactly how it works
Without further details nobody can answer then what you should do.
But if it's indeed a POST receival script on the local server, then you can send a POST request to it using the URL:
$url = "https://$_SERVER[SERVER_NAME]/path/to/api.php";
And then receive its output from the cURL call.
$data = curl($url)->post(1)->postdata(array("billing"=>1234345))
->returntransfer(1)->exec();
// (you would use the cumbersome curl_setopt() calls instead)
So you get a XML or JSON or whatever response.
If they're on the same drive, then use file operations instead:
file_put_contents('/path/to/the/file', $contents);
Using CURL should only be done if you absolutely NEED the http layer to get involved for some reason, or if you're dealing with a remote server. Using HTTP would also mean you need to have the 'target' script be able to handle a file upload plus whatever other data you need to send, and then that script would end up having to do file operations ANYWAYS, so in effect you've gone on a round-the-world flight just so you can move from your living room to the kitchen.
file://locafilespec.ext worked for me. I had 2 files in the same folder on a linux box, in a folder that is not served by my webserver, and I used the file:// wrapper to post to file://test.php and it worked great. it's not pretty, but it'll work for dev until I move it to it's final resting place.
Does curl have the ability to post to a local file or not?
To curl local file, you need to setup HTTP server as file:// won't work, so:
npm install http-server -g
Then run the HTTP server in the folder where is the file:
$ http-server
See: Using node.js as a simple web server.
Then test the curl request from the command-line to localhost like:
curl http://127.0.0.1:8081/file.html
Then you can do the same in PHP.

GWT with -noserver

I'm making a GWT project that uses PHP to connect to a DB2 database. When I compile the project and deploy it to the server (copy the contents of the WAR directory over), it works fine, obviously in hosted mode I run into the SOP issue since GWT is on port 8888 while the php script is running on port 80.
I'm trying to get the -noserver option to work but I must be missing something.. I went back and created the basic sample app from the command line (webApplicationCreator -out /home/mike/gwt/sample1)
I edited the build.xml to include the -noserver and -port 80 arguements for devmode. I want my app to be hosted at localhost/sample1 so I edited the -startupUrl to the whole URL I want to use: http://localhost/sample1/sample1.html
I compiled (ant), copied over the sample1.html, sample1.css from war to the webserver sample1 directory, and the (md5).gwt.rpc, clear.cache.gif, sample1.nocache.js and hosted.html files from the war/sample1 to sample1/sample1 directory as described in the GWT documentation (no history.html file was created).
I then run ant devmode from the project directory (/home/mike/gwt/sample1)
I can get to the sample1.html page, but when I click the button to send the name to the server it returns with
Remote Procedure Call - Failure
Server replies:
An error occurred while attempting to contact the server. Please check your network connection and try again.
I turned on firebug and it's returning a 404 for http://localhost/sample1/sample1/greet. This is where I'm stuck.. this file obviously doesn't exist on my webserver.. but why? Isn't this something that is supposed to be getting compiled by GWT?
Can anyone give me a hand? Thanks!
So, basically you've copied over the client-side of a client/server application. When your GWT client application attempts to make a Remote Procedure Call (RPC) to the server to a greeting service that is part of the initial sample, it can't find that service.
If you wanted to copy that service over, you'd need to have a Java application server, copy over the GreetingService, the web.xml that references it and possibly a few other things (I'd have to check in more detail). That doesn't sound like what you actually want, so either you'll want to build a GWT-RPC service in PHP that responds to that URL, or remove the reference in the GWT code to RPC call to the greeting service.
With a PHP back-end, you're probably not going to use GWT-RPC, I'm guessing that you're more likely to use JSON or XML, and if that's the case, then I'd go with removing the RPC call altogether for now.
Does this all make sense? Feel free to ask for further clarification.
To solve the SOP issue, I used the HttpProxyServlet to proxy the HTTP requests to my webserver through the development server.
Download httpProxyPackage.jar, copy it into WEB-INF/lib/, and configure it like so in WEB-INF/web.xml (this is for the StockWatcher tutorial, assuming your web root is the folder that contains the StockWatcher directory):
<servlet>
<servlet-name>jsonStockData</servlet-name>
<servlet-class>com.jsos.httpproxy.HttpProxyServlet</servlet-class>
<init-param>
<param-name>host</param-name>
<param-value>http://localhost/StockWatcher/war/stockPrices.php</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>jsonStockData</servlet-name>
<!--
http://127.0.0.1:8888/stockPrices.php in dev mode
http://gwt/StockWatcher/war/stockPrices.php in prod mode
-->
<url-pattern>/stockPrices.php</url-pattern>
</servlet-mapping>
Then redefine your JSON URL as:
GWT.getHostPageBaseURL() + "stockPrices.php?q=";
instead of:
GWT.getModuleBaseURL() + "stockPrices.php?q=";
It’s maybe not the best way, but if it can get someone else started… There was another way using php-cgi, but I didn’t have it installed.

PHP Subversion Setup FTP

I work at a small php shop and I recently proposed that we move away from using our nas as a shared code base and start using subversion for source control.
I've figured out how to make sure our dev server gets updated with every commit to our development branch... and I know how to merge into trunk and have that update our staging server, because we have direct access to both of these, but my biggest question is how to write a script that will update the production server, which we many times only have ftp access to. I don't want to upload the entire site every time... is there any way to write a script that is smart enough to upload only what has changed to the web server when we execute it (don't want it to automatically be uploading to the production enviroment, we want to execute it manually)?
Does my question even make sense?
Basically, your issue is that you can't use subversion on the production server. What you need to do is keep, on a separate (ideally identically configured) server a copy of your production checkout, and copy that through whatever method to the production server. You could think of this as your staging server, actually, since it will also be useful for doing final tests on releases before rolling them out.
As far as the copy goes, if your provider supports rsync, you're set. If you have only FTP you'll have to find some method of doing the equivalant of rsync via FTP. This is not the first time anybody's had that need; a web search will help you out there. But if you can't find anything, drop me a note and I'll look around myself a little further.
EDIT: Hope the author doesn't mind me adding this, but I think it belongs here. To do something approximately similar to rsync with ftp, look at weex http://weex.sourceforge.net/. Its a wrapper around command line ftp that uses a local mirror to keep track of whats on the remote server so that it can send only changed files. Works great for me.
It doesn't sound like SVN plays well with FTP, but if you have http access, that may prove sufficient to push changes using svnsync. That's how we push changes to our production severs -- we use svnsync to keep a read-only mirror of the repository available.
I use the following solution. Just install the SVN client on your webserver, and attach this into a privately accessible url:
<?php
// make sure you have a robot account that can't commit ;)
$username = Settings::Load()->Get('svn', 'username');
$password = Settings::Load()->Get('svn', 'password');
$repos = Settings::Load()->Get('svn', 'repository');
echo '<h1>updating from svn</h1><pre>';
// for secutity, define an array of folders that you do want to be synced from svn. The rest should be skipped.
$svnfolders = array( 'includes/' ,'plugins/' ,'images/' ,'templates/', 'index.php' => 'index.php');
if(!empty($_GET['justthisone']) && array_search($_GET['justthisone'], $svnfolders) !== false){ // you can also just update one of above by passing it to $_GET
$svnfiles = array($_GET['justthisone']);
}
foreach($svnfiles as $targetlocation)
{
echo system("svn export --username={$username} --password {$password} {$repos}{$targetlocation} ".dirname(__FILE__)."/../{$targetlocation} --force");
}
die("</pre><h1>Done!</h1>");
I'm going to make an assumption here and say you are using a post-commit hook to do your merging/updating of your staging server. This may work, but I would strongly recommend you look into a Continuous Integration solution. The following are some that I am aware of:
Xinc - http://code.google.com/p/xinc/ (PHP Specific)
CruiseControl - http://cruisecontrol.sourceforge.net/ (Wildly popular.)
PHP integration made possible with http://phpundercontrol.org/about.html
Hudson - [https://hudson.dev.java.net/] (Appears to be Java based, but allows for plugins/extensions)
LFTP is capable of synchronizing directories over ftp.
Just an idea:
You could hold a revision of your project on a host you have access to and where subversion is installed. This single revision reflects the production server's version.
You could now write a PHP script that makes this repository update over svn and then find all files that have been changed since the rep was updated. These files you can upload.
Such a script could look like this:
$path = realpath( '/path/to/production/mirror' );
chdir( $path );
$start = time();
shell_exec( 'svn co' );
$list = array();
$i = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $path ), RecursiveIteratorIterator::SELF_FIRST );
foreach( $i as $node )
{
if ( $node->isFile() && $node->getCTime() > $start )
{
$list[] = $node->getPathname();
}
// directories should also be handled
}
$conn = ftp_connect( ... );
// and so on
Just as it came to my mind.
I think this will help you
https://github.com/midhundevasia/deploy
its works well in Windows.

Categories